欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Ejb3学习之二----Ejb3的Ejb Bean类型介绍

程序员文章站 2024-02-23 10:21:52
...

关于Ejb3的Ejb bean类型介绍,有三种类型:Session bean,Entity Bean和MessageDriven bean(Mbean).在这篇文章中,主要介绍Session bean.
Key:
定义
Stateful bean
Stateless bean
Sample

一 Session Bean定义
用于实现业务逻辑,分为stateful bean(有状态的Session Bean)和Stateless Bean(无状态的Session Bean)。每当Client发出request时,容器就会查找对应的Session Bean来做响应。
二 Stateful Bean
  1.特点
可以保持每个客户端在请求处理中调用所有方法的状态。对于复杂业务的处理,尤其重要。例如:在在线购物系统中,每个客户都拥有购物车(Stateful bean),而装载的货物和货物的数量在Session Bean中通过方法来操作。因此,对于Stateful bean而言,系统需要用更多的内存来分配给bean,在性能不如Stateless Bean.
  2. 生命周期
   (1) 分为三个状态:就绪/不存在/**。
   (2) bean初始化时,会发生如下过程:容器调用newInstance方法;如果bean使用DI,所有依赖的资源、bean和环境组件都要注入进来。session bean的初始化可以在装载配置文件时开始,也可以在用户首次调用该bean时开始.
   (3) 池化:类似数据库的连接池.ejb的“池”开启时会先创建一定的bean实例(默认的数目,不过不知道具体是多少),如果不够用了再创建新的实例,是被客户端删除或超时的时候被销毁。此外,如果客户端删除了Ejb bean,则和Ejb Bean相关联的其他bean也会一同被删除。
  3. 方法
    在Ejb容器中,供Stateful bean而言,有五个方法可以被调用:setSessionContext,ejbCreate,ejbRemove,ejbActive,ejbPassivate.
  4. programs rules
    (1) 至少有一个业务接口。
    (2) 必须是具体类,不能是final或抽象类。
    (3) 必须有空构造函数。
    (4) 可以是其它sessionbean或pojo的子类。
    (5) 注解继承需要受到限制,超类中@Stateless or @Stateful注解在部署时将要被忽略。但定义的任何回调方法和资源注入都将被继承.
    (6) 必须定义所有的方法为public的,但不能是final或static的.在远程业务接口中的定义的参数和返回值类型必须实现java串行化接口.
    (7) bean实例变量用于存储会话状态,这些变量必须是java基本数据类型或实现串行化接口.
    (8) bean由于不能池化和进行重用,如果没有方式进行销毁会非常危险,因此必须定义业务方法进行销毁.我们使用@Remove注解。
    (9) 除了postContruct和preDestory外,bean还有prePassivate和postAcitivate生命周期回调方法。分别在钝化前和**后调用。
三 Stateless bean
   1. 特点
    不能保留处理过程中状态。所有的事务处理在一个方法中处理完成,并且能与其它用户共享信息。正因为如此,其性能较高。一般在实际应用中,都会进行序列化(Searialize).
   2. 生命周期
    (1) 分为两个状态:就绪和不存在。
    (2) bean初始化时,会发生如下过程:容器调用newInstance方法;如果bean使用DI,所有依赖的资源、bean和环境组件都要注入进来。session bean的初始化可以在装载配置文件时开始,也可以在用户首次调用该bean时开始.
    (3) 池化:类似数据库的连接池.ejb的“池”开启时会先创建一定的bean实例(默认的数目),如果不够用了再创建新的实例。一般是等“池”销毁的时候销毁,例如宕机的时候,或者必要的时候人为销毁。
    (4) 通过少量的实例来处理实际的并发的访问。理论上可以有多个@postContruct和@preDestroy生命周期回调方法,但很少这样做:PostConstruct--实例创建并DI之后调用,PreDestroy--bean销毁前调用,比如释放资源;生命周期回调方法不能有参数,而且不能抛出受检查的异常(运行时异常的子类)。
   3. 方法
     在Ejb容器中,供Stateless bean而言,有三个方法可以被调用: setSessionContext,ejbCreate,ejbRemove.
   4. program rules
    (1) 至少有一个业务接口。
    (2) 必须是具体类,不能是final或抽象类。
    (3) 必须有空构造函数。
    (4) 可以是其它sessionbean或pojo的子类。
    (5) 注解继承需要受到限制,超类中@Stateless or @Stateful注解在部署时将要被忽略。但定义的任何回调方法和资源注入都将被继承。
    (6) 必须定义所有的方法为public的,但不能是final或static的.在远程业务接口中的定义的参数和返回值类型必须实现java串行化接口.
四 Sample:
  1. Stateless Bean 实例:
    1) interface(HelloWorldEjb):
    

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. public interface HelloWorldEjb {    
  2. public String sayHelloWorld(String userName);    
  3. public int computeCallCount();    
  4. }  
public interface HelloWorldEjb { 
public String sayHelloWorld(String userName); 
public int computeCallCount(); 
}


   2) Ejb Session Bean:
  

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. import javax.ejb.Remote;    
  2. import javax.ejb.Stateless;    
  3. /**   
  4. * @author Jamson Huang   
  5.  
  6. */    
  7. @Stateless    
  8. @Remote    
  9. public class HelloWorldEjbBean implements HelloWorldEjb {    
  10. private int callCnt;    
  11. public String sayHelloWorld(String userName){    
  12. return "Hello World! "+userName;    
  13. }    
  14. public int computeCallCount(){    
  15. callCnt = callCnt+1;    
  16. return callCnt;   
  17.  }    
  18. }  
import javax.ejb.Remote; 
import javax.ejb.Stateless; 
/** 
* @author Jamson Huang 
* 
*/ 
@Stateless 
@Remote 
public class HelloWorldEjbBean implements HelloWorldEjb { 
private int callCnt; 
public String sayHelloWorld(String userName){ 
return "Hello World! "+userName; 
} 
public int computeCallCount(){ 
callCnt = callCnt+1; 
return callCnt;
 } 
}


deploy后,发布的Ejb bean name是HelloWorldEjbBean.
    3) Client:
   

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. import javax.naming.InitialContext;    
  2. import com.ejb.bean.HelloWorldEjb;    
  3. /**   
  4. * @author Jamson Huang   
  5. * @version 1.0.0   
  6. */    
  7. public class HelloWorldEjbClient {   
  8.  public static void main(String[] args) throws Exception{    
  9. // Properties props = new Properties();    
  10. //props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");    
  11. //props.setProperty("java.naming.provider.url", "localhost:1099");    
  12. // props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");    
  13.     InitialContext context = new InitialContext();    
  14.     HelloWorldEjb helloWorldEjb = (HelloWorldEjb)context.lookup("HelloWorldEjbBean/remote");         System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount()); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount());   
  15.  HelloWorldEjb helloWorldEjb2 = (HelloWorldEjb)context.lookup("HelloWorldEjbBean/remote"); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount());    
  16. }    
  17. }  
import javax.naming.InitialContext; 
import com.ejb.bean.HelloWorldEjb; 
/** 
* @author Jamson Huang 
* @version 1.0.0 
*/ 
public class HelloWorldEjbClient {
 public static void main(String[] args) throws Exception{ 
// Properties props = new Properties(); 
//props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory"); 
//props.setProperty("java.naming.provider.url", "localhost:1099"); 
// props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming"); 
    InitialContext context = new InitialContext(); 
    HelloWorldEjb helloWorldEjb = (HelloWorldEjb)context.lookup("HelloWorldEjbBean/remote");         System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount()); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount());
 HelloWorldEjb helloWorldEjb2 = (HelloWorldEjb)context.lookup("HelloWorldEjbBean/remote"); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); 
} 
}


run :

Console代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. Hello World! Jamson    
  2. 5    
  3. Hello World! Jamson    
  4. 6    
  5. Hello World! Jamson    
  6. 7    
  7. Hello World! Jamson    
  8. 8  
Hello World! Jamson 
5 
Hello World! Jamson 
6 
Hello World! Jamson 
7 
Hello World! Jamson 
8


可以看出,在Stateless bean中,其信息被其它所有用户共享。
  2. stateful bean
    1) interface:
  

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1.    /**   
  2. * @author Jamson Huang   
  3.  
  4. */  
  5.  public interface HelloWorldStatefulEjb {    
  6. public String sayHelloWorld(String userName);    
  7. public int computeCallCount();    
  8. }  
   /** 
* @author Jamson Huang 
* 
*/
 public interface HelloWorldStatefulEjb { 
public String sayHelloWorld(String userName); 
public int computeCallCount(); 
}


   2) Ejb bean:
 

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. import javax.ejb.Remote;    
  2. import javax.ejb.Stateful;    
  3. /**   
  4. * @author Jamson Huang   
  5.  
  6. */    
  7. @Stateful    
  8. @Remote    
  9. public class HelloWorldStatefulEjbBean implements HelloWorldStatefulEjb {    
  10. private int callCnt;    
  11. public String sayHelloWorld(String userName){    
  12. return "Hello World! "+userName;    
  13. }    
  14. public int computeCallCount(){   
  15.  callCnt = callCnt+1;    
  16. return callCnt;    
  17. }    
  18. }  
import javax.ejb.Remote; 
import javax.ejb.Stateful; 
/** 
* @author Jamson Huang 
* 
*/ 
@Stateful 
@Remote 
public class HelloWorldStatefulEjbBean implements HelloWorldStatefulEjb { 
private int callCnt; 
public String sayHelloWorld(String userName){ 
return "Hello World! "+userName; 
} 
public int computeCallCount(){
 callCnt = callCnt+1; 
return callCnt; 
} 
}


deploy后,其Session bean name为:HelloWorldStatefulEjbBean。
   3) Client:
  

Java代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. import javax.naming.InitialContext;    
  2. import com.ejb.bean.HelloWorldStatefulEjb;    
  3. /**   
  4. * @author Jamson Huang   
  5. * @version 1.0.0   
  6. */ public class HelloWorldStatefulEjbClient {    
  7. public static void main(String[] args)throws Exception{    
  8. // Properties props = new Properties();   
  9.  // props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");   
  10.  // props.setProperty("java.naming.provider.url", "localhost:1099");    
  11. // props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");    
  12. InitialContext context = new InitialContext();    
  13. HelloWorldStatefulEjb helloWorldEjb = (HelloWorldStatefulEjb)context.lookup("HelloWorldStatefulEjbBean/remote"); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount()); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount());    
  14. HelloWorldStatefulEjb helloWorldEjb2 = (HelloWorldStatefulEjb)context.lookup("HelloWorldStatefulEjbBean/remote"); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount());    
  15. }    
  16. }  
import javax.naming.InitialContext; 
import com.ejb.bean.HelloWorldStatefulEjb; 
/** 
* @author Jamson Huang 
* @version 1.0.0 
*/ public class HelloWorldStatefulEjbClient { 
public static void main(String[] args)throws Exception{ 
// Properties props = new Properties();
 // props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
 // props.setProperty("java.naming.provider.url", "localhost:1099"); 
// props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming"); 
InitialContext context = new InitialContext(); 
HelloWorldStatefulEjb helloWorldEjb = (HelloWorldStatefulEjb)context.lookup("HelloWorldStatefulEjbBean/remote"); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount()); System.out.println(helloWorldEjb.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb.computeCallCount()); 
HelloWorldStatefulEjb helloWorldEjb2 = (HelloWorldStatefulEjb)context.lookup("HelloWorldStatefulEjbBean/remote"); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); System.out.println(helloWorldEjb2.sayHelloWorld("Jamson")); System.out.println(helloWorldEjb2.computeCallCount()); 
} 
}


run,console出现的log信息:

Console代码 Ejb3学习之二----Ejb3的Ejb Bean类型介绍
  1. Hello World! Jamson    
  2. 1  
  3. Hello World! Jamson    
  4. 2    
  5. Hello World! Jamson    
  6. 1    
  7. Hello World! Jamson    
  8. 2  
Hello World! Jamson 
1
Hello World! Jamson 
2 
Hello World! Jamson 
1 
Hello World! Jamson 
2


说明每个Stateful bean,其资源是独立的,只能自己使用。

相关标签: Bean EJB JBoss