关于SessionBean的生命周期。
有状态的SessionBean的生命周期:
几个比较重要的注解:
@PostConstruct:当EJB实例被创建后会被自动调用。
@Remove:当EJB实例需要回收时调用,该注解用在EJB接口中任意方法上。
@PreDestory:当@Remove方法被调用时,该方法会被自动调用。
@PrePassivate:当EJB实例进入钝化状态前,会被调用。
@PostActivate:当EJB实例被激活后,会被调用。
以下的实例验证了上面这几个注解执行的时机。
服务器端程序:
@Stateful @Remote @CacheConfig(maxSize=2)//该注解定义了在EJB的实例池中最多只允许有2个实例。 public class StatefulEjbBean implements StatefulEjb { private int num; public void add(int i) { // TODO Auto-generated method stub num = num + i; } public int getResult() { // TODO Auto-generated method stub return num; } @PostConstruct public void postConstruct(){ System.out.println(this+" , postConstruct"); } @PrePassivate public void prePassivate(){ System.out.println(this+" , prePassivate"); } @PostActivate public void postActivate(){ System.out.println(this+" , postActivate"); } @Remove public void logout(){ System.out.println(this + " , remove"); } @PreDestroy public void preDestroy(){ System.out.println(this+" , PreDestroy"); } }
客户端程序:
public class StatefulEbjClient { public static void main(String[] args) { try { InitialContext context = new InitialContext(); //创建第一个EJB实例 //调试信息输出:org.leadfar.ejb.StatefulEjbBean@1b4c9f3 , postConstruct StatefulEjb fe = (StatefulEjb)context.lookup("StatefulEjbBean/remote"); fe.add(1); //创建第二个EJB实例 //调试信息输出:org.leadfar.ejb.StatefulEjbBean@10f7a0 , postConstruct StatefulEjb fe2 = (StatefulEjb)context.lookup("StatefulEjbBean/remote"); fe2.add(1); fe2.add(1); //创建第三个EJB实例,但是由于此时的EJB实例池中最多只能有两个实例,所以必须有一个实例被钝化。 //调试信息输出: //org.leadfar.ejb.StatefulEjbBean@8f362e , postConstruct //org.leadfar.ejb.StatefulEjbBean@1b4c9f3 , prePassivate 第一个实例被钝化,也就是服务器不再记录其状态。 StatefulEjb fe3 = (StatefulEjb)context.lookup("StatefulEjbBean/remote"); fe3.add(1); fe3.add(1); fe3.add(1); //调用第一个实例的getResult()方法,需要重新将第一个实例加入到实例池中,因此会调用激活方法。 //同时,会有另外一个实例被钝化。 //调试信息输出: //org.leadfar.ejb.StatefulEjbBean@da7dd , postActivate 需要注意:可以看出此时激活的实例已经不是之前的第一个了,因为服务器重新创建了一个新的实例,只不过该实例拥有之前第一个实例的状态信息。 //org.leadfar.ejb.StatefulEjbBean@10f7a0 , prePassivate 第二个实例被钝化。 System.out.println(fe.getResult()); //当@Remove的方法被调用时,@PreDestroy方法会被自动调用。 //调试信息: //org.leadfar.ejb.StatefulEjbBean@da7dd , remove //org.leadfar.ejb.StatefulEjbBean@da7dd , PreDestroy fe.logout(); //由于fe2实例已经被钝化,此时需要完成的操作是先将该实例激活,然后再执行上面一样的操作。 //调试信息: //org.leadfar.ejb.StatefulEjbBean@16bb9f7 , postActivate //org.leadfar.ejb.StatefulEjbBean@16bb9f7 , remove //org.leadfar.ejb.StatefulEjbBean@16bb9f7 , PreDestroy fe2.logout(); fe3.logout(); } catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
这段程序就可以充分说明一个有状态的SessionBean实例的各种状态。