文档:http://trailblazer.demo.jboss.com/EJB3Trail/background/deploy/index.html
代码:http://www.jboss.com/index.html?module=downloads&op=download&downloadId=41
下下来了! 跑一下看看,原来整个网站就是帮助文档本身,有各种各样EJB3各方面的例子。太多了,要是能找到一个简单一点的EAR的例子就好了。~_~ 言规正转:
The sample application in this TrailBlazer is on investment calculator. Based on your investment preference and the fund growth rate, it calculates the final payout at the end of your investment period. The calculator is bundled with this trail map and you can try it directly from the trail pages.
We will refactor the investment calculator several times to showcase how to use different technologies in the EJB 3.0 programming model
这个应用示例说的是一个investment calculator.根据你的个人投资偏好和资金的增长率,它能计算在投资期间你的支出。
然后这个investment calucator会使用EJB3.0中不同的技术进行多次重构~
这里有几个不错的链接可供收藏:
http://www.jboss.com/products/ejb3
http://docs.jboss.org/ejb3/app-server/tutorial/index.html
http://docs.jboss.org/ejb3/app-server/reference/build/reference/en/html/index.html(very good)
http://www.jcp.org/en/jsr/detail?id=220
http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
http://java.sys-con.com/read/48539.htm
http://www.onjava.com/pub/a/onjava/2004/04/21/declarative.html
下下来后点build.bat然后把生成的ear拷贝到deploy目录下,启动JBoss,并通过http://localhost:8080/EJB3Trail访问,
OK,第一天就结束了,下次见~
EAR的结构
-META-INF
--jboss-app.xml
--application.xml
-beans.jar
-web.war
第一The jboss-app.xml file defines a class loader for this application. It makes it simpler for EJB 3.0 to find the default EntityManager (see here). The content of the jboss-app.xml file is as follows.
<
jboss-app
>
<
loader-repository
>
trailblazer:app=ejb3
</
loader-repository
>
</
jboss-app
>
第二application.xml比较简单:
<
application
>
<
display-name
>
EJB3Trail
</
display-name
>
<
description
>
J2EE Made Easy Trail Map
</
description
>
<
module
>
<
ejb
>
beans.jar
</
ejb
>
</
module
>
<
module
>
<
web
>
<
web-uri
>
web.war
</
web-uri
>
<
context-root
>
EJB3Trail
</
context-root
>
</
web
>
</
module
>
</
application
>
beans.jar的结构,主要是看persistence.xml怎么写的
<
persistence
>
<
persistence-unit
name
="ejb3trail"
>
<
jta-data-source
>
java:/DefaultDS
</
jta-data-source
>
<
properties
>
<
property
name
="hibernate.hbm2ddl.auto"
value
="create-drop"
/>
</
properties
>
</
persistence-unit
>
</
persistence
>
中间的properties与Hibernate本是同根生,它们的默认值可以在D:\jboss-4.0.4.GA\server\default\deploy\ejb3.deployer\META-INF\persistence.properties中找到。
这里的create-drop的意思是Hibernate会自动根据POJO和标注建表和删除表,第一次用的时候发现该死的JBOSS把我在MySQL中建的表全部删除了,后来赶紧把这句注释掉~
OK,第二天就到这里。
Service object management 的优点:
Loose coupling
可以拥有不同的实现而不必修改客户端
It only needs to know the service interface and look up the service stub object from the server using the interface name or a pre-argeed string name
Network independent
服务可以通过各种不同方式HTTP, TCP, and messaging queues提供给客户
The client just looks up a stub of service object and call any method defined in the service interface as if it is a local call
Resource pools
服务维护对象池,客户不必关心对象的创建,销毁。
The client application does not need to remember to destroy objects or close connections etc
In EJB 3.0, all the managed service objects are POJOs, POJO + Anotation就是EJB3.0的编程方式。
第一SLSB, 多对一的关系
例子一是写一个SLSB类型的inverstment caculator,然后在JSP或Swing UI中使用它的calculate服务:
步骤一
首先要定义一个接口包含所有的业务方法,这个接口是一个没有使用annotation的POJI
public
interface
Calculator {
public
double
calculate (
int
start,
int
end,
double
growthrate,
double
saving);
}
步骤二
定义好接口后,然后就是EJB3实现了
@Stateless
public
class
StatelessCalculator
implements
Calculator, RemoteCalculator {
public
double
calculate (
int
start,
int
end,
double
growthrate,
double
saving) {
double
tmp
=
Math.pow(
1
.
+
growthrate
/
12
.,
12
.
*
(end
-
start)
+
1
);
return
saving
*
12
.
*
(tmp
-
1
)
/
growthrate;
}
}
这个实现很容易看懂啦,然后把它打成jar包发布到deploy下面就可以用了~
下面这段实在太精典了,忍不住多看了几遍
Once the session bean is deployed into the EJB 3.0 container, a stub object is created and it is registered in the server's JDNI registry. The client code obtains a stub of the bean from the JNDI using its default JNDI name formatted as follows.
If the application is deployed in a EAR file, the default JNDI name is the EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local for the stub for local interface. For the remote interface (see below), it is EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local.
If the bean is deployed in a JAR file, the JNDI names are EJB-CLASS-NAME/local and EJB-CLASS-NAME/remote.
接下来是JSP,
<%
@ page
import
=
"
trail.slsb.*, javax.naming.*, java.text.*
"
%>
<%!
private
Calculator cal
=
null
;
public
void
jspInit () {
try
{
InitialContext ctx
=
new
InitialContext();
cal
=
(Calculator) ctx.lookup(
"
EJB3Trail/StatelessCalculator/local
"
);
}
catch
(Exception e) {
e.printStackTrace ();
}
}
%>
<%
String result;
int
start
=
25
;
int
end
=
65
;
double
growthrate
=
0.08
;
double
saving
=
300.0
;
try
{
start
=
Integer.parseInt(request.getParameter (
"
start
"
));
end
=
Integer.parseInt(request.getParameter (
"
end
"
));
growthrate
=
Double.parseDouble(request.getParameter (
"
growthrate
"
));
saving
=
Double.parseDouble(request.getParameter (
"
saving
"
));
NumberFormat nf
=
NumberFormat.getInstance();
nf.setMaximumFractionDigits(
2
);
result
=
nf.format(cal.calculate(start, end, growthrate, saving));
}
catch
(Exception e) {
//
e.printStackTrace ();
result
=
"
Not valid
"
;
}
%>
<
html
>
<
body
>
<
p
>
Investment calculator
<
br
/>
<
form action
=
"
calculator.jsp
"
method
=
"
POST
"
>
Start age
=
<
input type
=
"
text
"
name
=
"
start
"
value
=
"
<%=start%>
"
><
br
/>
End age
=
<
input type
=
"
text
"
name
=
"
end
"
value
=
"
<%=end%>
"
><
br
/>
Annual Growth Rate
=
<
input type
=
"
text
"
name
=
"
growthrate
"
value
=
"
<%=growthrate%>
"
><
br
/>
Montly Saving
=
<
input type
=
"
text
"
name
=
"
saving
"
value
=
"
<%=saving%>
"
><
br
/>
<
input type
=
"
submit
"
value
=
"
Calculate
"
>
<
INPUT type
=
"
button
"
value
=
"
Close Window
"
onClick
=
"
window.close()
"
>
</
form
>
</
p
>
<
p
>
The result from the last calculation: The balance at the End age is
<
b
><%=
result
%></
b
></
p
>
</
body
>
</
html
>
第一个例子,不全部拷贝下来心里不舒服~
下面的东西又是比较重要的:
一个sessionbean可以同时实现local和remote接口,每种都针对一种不同的客户,默认是local,针对在同一个JVM上调用的,比如上例
另一种是Remote,性能稍差,尽量不用。
下面是一个使用了两个接口的session bean的例子
@Stateless
@Local ({Calculator.
class
})
@LocalBinding (jndiBinding
=
"
EJB3Trail/LocalCalculator
"
)
@Remote ({RemoteCalculator.
class
})
@RemoteBinding (jndiBinding
=
"
EJB3Trail/RemoteCalculator
"
)
public
class
LocalRemoteCalculator
implements
Calculator, RemoteCalculator {
public
double
calculate (
int
start,
int
end,
double
growthrate,
double
saving) {
double
tmp
=
Math.pow(
1
.
+
growthrate
/
12
.,
12
.
*
(end
-
start)
+
1
);
return
saving
*
12
.
*
(tmp
-
1
)
/
growthrate;
}
public
String getServerInfo () {
return
"
This is the JBoss EJB 3.0 TrailBlazer
"
;
}
}
@Local表示它是本地的,可以通过接口Caculator来调用
@Remote表示这是远程的,可以通过接口RemoteCalculator来调用
@jndiBinding则表示从JNDI中如何找到它们。
也可以这样
@Remote
public interface RemoteCalculator {
// ... ...
}
在接口上面标注,这样那个实现类就不用再标注~