/**
*
* stateless session bean有两个状态:
* Does Not Exist
* ^@PreDestroy |
* | |
* | |
* | |
* | |Class.newInstance()
* | v@PostConstruct
* Method-Ready pool
* | ^(业务方法调用)
* |_______|
*
* 本地接口的标注(注解):
* @Local
*
* 远程接口的标注(注解):
* @Remote
*
* 实现类的标注(注解):
* @Stateless 表明是个stateless bean
* @Local(XXX.class) 声明本地接口(如果实现类已经继承了本地和远程接口, 那么实现类就不用加此标注了. )
* @Remote(XXX.class) 声明远程接口(如果实现类已经继承了本地和远程接口, 那么实现类就不用加此标注了. )
* @LocalBinding(jndiBinding="XXX1/XXX2/local") 本地jndi绑定
* @RemoteBinding(jndiBinding="XXX1/XXX2/remote") 远程jndi绑定
* 添加此两个标注时出现了NullPointerException, 因为忘了在本地接口和远程接口添加@Local和@Remote标注
*
* 回调方法的标注(注解):
* @PostConstruct 状态由DNE到MRP的回调方法 对象完成实例化之后被调用
* @PreDestroy 状态由MRP到DNE的回调方法 对象被销毁之前被调用
* @PrePassivate 当一个有状态的SessionBean实例空闲时间过长,容器会钝化(Passivate)它,并把它的状态保存到缓存中。
* 使用这个注释的方法会在容器钝化bean实例之前调用,适用于有状态的bean。
* @PostActivate,当客户端再次使用已经被钝化的有状态sessionbean时,新的实例被创建,状态被恢复。
* 使用此注释的sessionbean会在bean激活完成时调用。适用有状态的bean。
* @Init 这个注释指定了有状态的sessionbean初始化的方法。它区别于@PostConstruct注释在于:@Init注释方法可以同时存在于
* 有状态sessionbean中,但每个实例bean只有一个被@Init注释的方法调用,它在@PostConstruct之前调用
* 回调方法可以使用任何名称, 但是必须是public, 返回void, 不带参数, 且不抛出任何checked exception的方法.
*
*/
实例如下:
package org.tuturial.sessionbeans.ejb;
public interface HelloWorld {
public String sayHello(String name);
}
package org.tuturial.sessionbeans.ejb;
import javax.ejb.Remote;
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld{
public String sayHello(String name){
return name+ "说:你好,世界";
}
}
<target name="ear_HelloWorldStateless" depends="build-project">
<jar destfile="bin/HelloWorldStateless.jar">
<fileset dir="bin">
<include name="org/tuturial/sessionbeans/ejb/*.class" />
</fileset>
</jar>
<mkdir dir="bin/HelloWorld" />
<ear destfile="bin/HelloWorld/HelloWorldStateless.ear" appxml="deploy/app_HelloWorldStateless.xml">
<fileset dir="bin">
<include name="HelloWorldStateless.jar" />
</fileset>
</ear>
</target>
其中对于有无状态的sessionbean的生命周期如下:
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());
}
%>