EJB 3.0入门:Stateless Session Beans
EJB容器的一个重要功能是管理服务对象。该容器实例化对象,管理器生命周期,维护对象池,提供从应用程序其他部分访问对象的方法。一个EJB 3.0 session bean是一个由EJB容器管理的POJO。在这个例子的以后部分我们将看到,一个session bean允许我们使用容器的安全,事务,消息,持久,和其他服务。
一个session bean的功能由它的服务interface 定义,该interface是一个plain old Java interface。利用interface 类名,session bean根据服务器的JNDI,回复该bean的stub对象。该 stub对象实现了该bean的服务接口。然后客户端即可呼叫bean的接口函数。stub对象简单地将呼叫传递给容器中的实际bean进程,容器来实现函数,做实际工作。stub对象由EJB容器自动生成,stub对象知道如何将对bean函数的呼叫告知容器--你无需提供stub对象的实现。
对stateless session bean来说,客户端stub对象能将你对函数的调用路由到恰好在容器管理的对象池中存在的bean进程。因此,你不能在bean类中存在任何保存bean状态的属性。负责,任何依靠这些属性的函数在经过一段时间后会发生不可预知错误。
例子程序:
建立一个stateless session bean,执行投资计算。客户端程序(一个servlet 或rich UI client)从容器中取得一个bean的reference ,并使用它的计算服务。
定义session bean接口
首先应定义包含商业函数的服务接口。该session bean接口仅仅是plain old Java接口,没有任何annotation。客户端利用该接口从EJB 3.0 容器取得session bean的stub对象。
public interface Calculator {
public double calculate (int start, int end,
double growthrate, double saving);
}
session bean 实现
bean实现是一个简单POJO。EJB 3,0 容器自动实例化并且管理POJO进程。以下是StatelessCalculator类的代码。 @Stateless标注表明该bean是一个stateless session bean。
一个session bean能实现多个接口。每个接口针对不同类型的客户端。默认情况,接口服务于“本地”客户端,运行于EJB 3.0容器的同一个JVM。例如,以上例子中,JSP页面和EJB 3.0容器运行于JBoss的JVM。当客户端通过本地接口查找bean stub时,容器返回session bean对象的Java reference。对Java reference的函数调用非常快速、高效。
另外一种session bean接口是remote interface,服务于remote客户端。当客户端通过远程接口查找bean stub时,容器返回一系列实现远程接口的stub对象。远程stub懂得怎样把 remote procedure calls (RPCs)传给服务器,即使是在一个集群环境下。远程接口也是一个plain old Java接口。远程接口可以包含与本地接口相同的method。但多数情况下,你可能通过内地和远程接口揭示不同的method。例如,对
public interface RemoteCalculator {
public double calculate (int start, int end,
double growthrate, double saving);
public String getServerInfo ();
}
完整代码:
摘要
在本节学习了怎样开发stateless session bean。下一节,我们将讨论另一类型的session beans,stateful session beans,在web应用中非常重要。
翻译自:
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/slsb/index.html
一个session bean的功能由它的服务interface 定义,该interface是一个plain old Java interface。利用interface 类名,session bean根据服务器的JNDI,回复该bean的stub对象。该 stub对象实现了该bean的服务接口。然后客户端即可呼叫bean的接口函数。stub对象简单地将呼叫传递给容器中的实际bean进程,容器来实现函数,做实际工作。stub对象由EJB容器自动生成,stub对象知道如何将对bean函数的呼叫告知容器--你无需提供stub对象的实现。
对stateless session bean来说,客户端stub对象能将你对函数的调用路由到恰好在容器管理的对象池中存在的bean进程。因此,你不能在bean类中存在任何保存bean状态的属性。负责,任何依靠这些属性的函数在经过一段时间后会发生不可预知错误。
例子程序:
建立一个stateless session bean,执行投资计算。客户端程序(一个servlet 或rich UI client)从容器中取得一个bean的reference ,并使用它的计算服务。
定义session bean接口
首先应定义包含商业函数的服务接口。该session bean接口仅仅是plain old Java接口,没有任何annotation。客户端利用该接口从EJB 3.0 容器取得session bean的stub对象。
public interface Calculator {
public double calculate (int start, int end,
double growthrate, double saving);
}
session bean 实现
bean实现是一个简单POJO。EJB 3,0 容器自动实例化并且管理POJO进程。以下是StatelessCalculator类的代码。 @Stateless标注表明该bean是一个stateless session bean。
一旦session bean被部署到EJB 3.0容器,一个stub对象即创建,并在服务器的JDNI注册器处注册。客户端从JNDI注册器处取得bean的一个stub,默认JNDI名格式如下:
- 如果应用是部署到EAR文件,默认JNDI名的格式是:本地接口的stub:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local。 远端接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
- 如果bean被部署到JAR文件,JNDI名是EJB-CLASS-NAME/local and EJB-CLASS-NAME/remote。
以下是JSP页面取得Calculator接口的stub进程的一个例子。你可以调用stub对象的函数,该调用被分配到
EJB 3.0容器的bean进程。
private Calculator cal = null;
public void jspInit () {
try {
InitialContext ctx = new InitialContext();
cal = (Calculator) ctx.lookup(
"EJB3Trail/StatelessCalculator/local");
} catch (Exception e) {
e.printStackTrace ();
}
}
// ... ...
public void service (Request req, Response rep) {
// ... ...
double res = cal.calculate(start, end, growthrate, saving);
}
public void jspInit () {
try {
InitialContext ctx = new InitialContext();
cal = (Calculator) ctx.lookup(
"EJB3Trail/StatelessCalculator/local");
} catch (Exception e) {
e.printStackTrace ();
}
}
// ... ...
public void service (Request req, Response rep) {
// ... ...
double res = cal.calculate(start, end, growthrate, saving);
}
远端与本地接口
一个session bean能实现多个接口。每个接口针对不同类型的客户端。默认情况,接口服务于“本地”客户端,运行于EJB 3.0容器的同一个JVM。例如,以上例子中,JSP页面和EJB 3.0容器运行于JBoss的JVM。当客户端通过本地接口查找bean stub时,容器返回session bean对象的Java reference。对Java reference的函数调用非常快速、高效。
另外一种session bean接口是remote interface,服务于remote客户端。当客户端通过远程接口查找bean stub时,容器返回一系列实现远程接口的stub对象。远程stub懂得怎样把 remote procedure calls (RPCs)传给服务器,即使是在一个集群环境下。远程接口也是一个plain old Java接口。远程接口可以包含与本地接口相同的method。但多数情况下,你可能通过内地和远程接口揭示不同的method。例如,对
CalculatorBean
bean来说,远程接口可能显示一个additional method,以给远程客户端一些服务器信息。public interface RemoteCalculator {
public double calculate (int start, int end,
double growthrate, double saving);
public String getServerInfo ();
}
注:使用远程接口包括对stub的序列化和去序列化,所有对bean进程的呼叫都通过网络。与本地接口相比效率低得多。应避免通过本地客户端查询远程接口。
对于session bean实现,可以使用 @Local
和 @Remote 标注区分bean的本地和远程接口。也可使用
@LocalBinding
和 @RemoteBinding 区分
两种接口的JNDI名称。下面是一个例子,实现了本地和远程接口的
JNDI绑定。
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 ({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
和 @Remote标注也可用来标记
session bean接口,而不是bean的实现类。例如,以下代码片断指明了RemoteCalculator是一个远程接口。由此,在
CalculatorBean
中,你不再需要
@Remote标记。
@Remote
public interface RemoteCalculator {
// ... ...
}
public interface RemoteCalculator {
// ... ...
}
完整代码:
EJB server
- Calculator.java: 本地接口
- StatelessCalculator.java: 本地接口的session bean实现
- RemoteCalculator.java: 远程接口
- StatelessCalculator2.java: 远程接口的session bean实现 with alternative JNDI binding names
EJB client
- calculator.jsp: calculator session bean的客户端 (使用本地接口)
摘要
在本节学习了怎样开发stateless session bean。下一节,我们将讨论另一类型的session beans,stateful session beans,在web应用中非常重要。
翻译自:
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/slsb/index.html