1. 有状态会话Bean会为每一个客户端创建一个实例,保持了用户的信息,如购物车,用户每调用一次lookup()都将创建一个新的Bean实例,如果希望一直使用某个Bean实例,则必须在客户端缓存存根。
2. 开发Statefull Session Bean 与Stateless Session Bean 的开发步骤相同
@Stateful
@Remote(Cart.class)
public class CartBean implements Cart {。。。。}
3. Statefull Session Bean 最好实现Serializable接口,这样EJB容器才能在它们不再使用时把它们序列化保存到硬盘上。
4. Statefull Session Bean 的生命周期包含3种状态:does not exist、method-ready和passivated。
5. 可以通过注释定义Session Bean的生命周期事件的回调方法,在EJB3.0,Bean可以有任意数量、任意名字的回调方法。
- @PostConstruct:当Bean对象完成实例化后,这个注释标注的方法会被立即调用,每个Bean class 只能定义一个@PostConstruct方法,这个注释同时适用于有状态和无状态会话Bean。
- @PreDestroy : 在容器销毁一个无用的或者过期的Bean实例之前,这个注释标注的方法会被调用,这个注释同时适用于有状态和无状态会话Bean。
- @PrePassivate :当一个有状态Bean实例空闲时间过长,就会发生钝化(passivate),如果仍然没有用户对Bean实例进行操作,容器会从硬盘中删除它,这个注释只适用于有状态会话Bean。
- @PostActivate : 当客户端再此使用已经被钝化的有状态Bean时,容器会重新实例化一个Bean实例,并从硬盘中将之前的状态恢复。标注了这个注释的方法会在激活完成时被调用。这个注释只适用于有状态会话Bean.
- @Init ::这个注释指定了有状态Bean的初始化方法,他区别于@PostConstruct注释的地方在于:多个@Init注释方法可以同时存在于有状态Session Bean中,但每个Bean 实例只会有一个@Init注释的方法被调用。@PostConstruct 在@Init之后被调用。
- @Remove : 当客户端调用标注了@Remove的方法时,容器会在方法执行后把Bean实例删除。
6. 拦截器可以拦截Session bean 和 Message-Driven Bean 的方法或生命周期事件。拦截器可以使同一Bean类中的方法或是一个外部类。
- 在Session Bean 中使用外部拦截器类:
@Stateless
@Remote(HelloChinaRemote.class)
@Local(HelloChina.class)
@Interceptors(HelloInterceptor.class)
public class HelloChinaBean implements HelloChinaRemote, HelloChina {..}
@Interceptors注释指定一个或多个在外部类中定义的拦截器,多个拦截器类之间用逗号分隔,如@Interceptors({A.class,B.class,C.class}),如果只有一个拦截器可省略大括号。如果只需对某一个方法进行拦截,可以将该注释标注在方法上面。
7. 拦截器:
public class HelloInterceptor {
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception{
//在这里插入代码
return ctx.proceed();
}catch(Exception e) {
throw e;
}
}
@ AroundInvoke 注释指定了要用作拦截器的方法,用@AroundInvoke注释指定的方法必须遵守以下格式:
public Object XXX(javax.interceptor.InvocationContext ctx) throws Exception
- 除了可以在外部类定义拦截器之外,也可以再Session Bean 内部将Bean的一个或多个方法定义为拦截器。
- 通过 ejb-jar.xml 可以定义默认拦截器, ejb-jar.xml 文件需要置于 jar 文件的 META-INF 目录:
<? xml version = "1.0" encoding = "UTF-8" ?>
< ejb-jar version = "3.0" xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xml = "http://www.w3.org/XML/1998/namespace" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd " >
< assembly-descriptor >
< interceptor-binding >
< ejb-name > * </ ejb-name >
< interceptor-class > cn.csu.ejb3.imple.HelloInterceptor</ interceptor-class >
</ interceptor-binding >
</ assembly-descriptor >
</ ejb-jar >
l <ejb-name>*</ejb-name> 指明拦截所有的 EJB 的所有方法。如果只想拦截某一个 EJB ,则可以用这个 EJB 的名称替换通配符“ * ”。其效果和在 Bean 类上标识 @Interceptor 的效果 是一样的。
l <intercepter-class> 用来指定拦截器类。
- 禁用拦截器
通过@ExcludeDefaultInterceptors注释禁用默认拦截器,该注释加在类上面。
8 通过 @EJB 注释可以注入 EJB, 通过 @Resource 可以注入资源类型。