关于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实例的各种状态。