📄 123.txt
字号:
Session Bean 的生命周期
EJB容器创建和管理session bean实例,有些时候,你可能需要定制session bean的管理过程。例如,你可能想在创建session bean实例的时候初始化字段变量,或在bean实例被销毁的时候关掉外部资源。上述这些,你都可能通过在bean 类中定义生命周期的回调方法来实现。这些方法将会被容器在生命周期的不同阶段调用(如:创建或销毁时)。通过使有下面所列的注释,EJB 3.0允许你将任何方法指定为回调方法。这不同于EJB 2.1,EJB 2.1 中,所有的回调方法必须实现,即使是空的。EJB 3.0中,bean可以有任意数量,任意名字的回调方法。
?@PostConstruct:当bean对象完成实例化后,使用了这个注释的方法会被立即调用。这个注释同时适用于有状态和无状态的会话bean。
?@PreDestroy:使用这个注释的方法会在容器从它的对象池中销毁一个无用的或者过期的bean 实例之前调用。这个注释同时适用于有状态和无状态的会话bean。
?@PrePassivate:当一个有状态的session bean实例空闲过长的时间,容器将会钝化(passivate)它,并把它的状态保存在缓存当中。使用这个注释的方法会在容器钝化bean实例之前调用。这个注释适用于有状态的会话bean。
当钝化后,又经过一段时间该bean 仍然没有被操作,容器将会把它从存储介质中删除。以后,任何针对该bean方法的调用容器都会抛出例外。
?@PostActivate:当客户端再次使用已经被钝化的有状态session bean时,新的实例被创建,状态被恢复。
使用此注释的session bean会在bean的激活完成时调用。这个注释只适用于有状态的会话bean。
?@Init:这个注释指定了有状态session bean初始化的方法。它区别于@PostConstruct注释在于:多个@Init注释方法可以同时存在于有状态session bean 中,但每个bean实例只会有一个@Init注释的方法会被调用。这取决于bean是如何创建的(细节请看EJB 3.0规范)。@PostConstruct在@Init之后被调用。
另一个有用的生命周期方法注释是@Remove,特别是对于有状态session bean。当应用通过存根对象调用使用了@Remove注释的方法时,容器就知道在该方法执行完毕后,要把bean实例从对象池中移走。
下面是这些生命周期方法注释在LifeCycleBean中的一个示例:
LifeCycleBean.java
//author:lihuoming
package com.foshanshop.ejb3.impl;
import com.foshanshop.ejb3.LifeCycle;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Init;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Remote;
import javax.ejb.Remove;
import javax.ejb.Stateful;
@Stateful
@Remote ({LifeCycle.class})
public class LifeCycleBean implements LifeCycle {
public String Say() {
try {
Thread.sleep(1000*30);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "这是会话Bean生命周期应用例子";
}
@Init
public void initialize () {
System.out.println("initialize()方法被调用");
}
@PostConstruct
public void Construct () {
System.out.println("Construct()方法被调用");
}
@PreDestroy
public void exit () {
System.out.println("exit()方法被调用");
}
@PrePassivate
public void serialize () {
System.out.println("serialize()方法被调用");
}
@PostActivate
public void activate () {
System.out.println("activate()方法被调用");
}
@Remove
public void stopSession () {
System.out.println("stopSession()方法被调用");
//调用该方法以通知容器移除该bean实例、终止会话。方法体可以是空的。
}
}
本例子的运行结果输出在Jboss控制台,请仔细观察。
下面是LifeCycleBean的Remote接口
LifeCycle.java
//author:lihuoming
package com.foshanshop.ejb3;
public interface LifeCycle {
public String Say();
public void stopSession ();
}
下面是Session Bean的JSP 客户端代码:
LifeCycleTest.jsp
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="com.foshanshop.ejb3.LifeCycle, javax.naming.*, java.util.Properties"%>
<%
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");
try {
LifeCycle lifecycle = (LifeCycle) session.getAttribute("lifecycle");
if (lifecycle == null) {
InitialContext ctx = new InitialContext(props);
lifecycle = (LifeCycle) ctx.lookup("LifeCycleBean/remote");
session.setAttribute ("lifecycle", lifecycle);
}
out.println(lifecycle.Say());
out.println("<BR>请注意观察Jboss控制台输出.等待9分钟左右,容器将会钝化此会话
Bean,@PrePassivate注释的方法将会执行<BR>");
out.println("<font color=red>你可以执行会话Bean的stopSession方法,把会话Bean实例从
对象池中移走。在销毁这个会话Bean之前将会执行 @PreDestroy注释的方法<BR></font>");
/*
lifecycle.stopSession();
*/
} catch (Exception e) {
out.println(e.getMessage());
}
%>
本例子的EJB 源代码在SessionBeanLifeCycle 文件夹(源代码下载:http://www.foshanshop.net/),项目中使用到的类库在上级目录lib 文件夹下。要发布本例子EJB (确保配置了环境变量JBOSS_HOME 及启动了Jboss),你可以执行Ant 的deploy 任务。
本例子的客户端代码在EJBTest文件夹,要发布客户端应用,你可以执行Ant 的deploy任务。通过
http://localhost:8080/EJBTest/LifeCycleTest.jsp访问客户端。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -