你不仅能拦截EJB方法的调用,也可以拦截EJB生命周期事件.这些回调可以被用于初始化你的EJB组件类的状态,如同拦截器类本身.生命周期的拦截非常类似于@AroundInvoke 类型:
@<callback-annotation> void
<method-name>(InvocationContext
ctx);
要想拦截一个EJB的回调,定义一个方法在你的拦截器类中与你感兴趣的回调一起注释.方法的返回值必需是void因为EJB回调没有返回值.方法名可以是任意的并且必需不抛出任何检查异常(没有throws子句).InvocationContext是这个方法的唯一参数.同@AroundInvoke方法,回调拦截的调用在一个大的Java调用栈中.这意味着你必需调用InvocationContext.proceed( )方法来完成生命周期事件.当proceed( )被调用时下一个拦截器类的相同回调被调用.如果没有其它的回调方法,那么proceed( )是一个no-op.因为没有回调方法InvocationContext.getMethod( )方法总是返回null.
定制注入注释
为什么要拦截一个EJB的回调?一个具体的例子是当你想要创建和定义你自己的注入注释.EJB规范中有一组注释为你注入J2EE资源,服务,和EJB引用到你的组件类中.一些应用程序服务器或应用程序像使用JNDI作为全局注册配置或没有J2EE服务的.不幸的是,规范定义没有方法直接注入全局的JNDI到你的组件中.我们怎样做来定义我们自己的注释提供这种功能和实现它作为一个拦截器.
首先我们要做的是定义我们将要使用从JNDI注入的注释:
package com.titan.annotations;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JndiInjected {
String value( );
}
@com.titan.annotations.JndiInjected注释的value()属性是对象的全局JNDI名字,我们想要注入的字段或setter方法.这是一个我们怎样使用自定义注释的例子:
@Stateless
public class MySessionBean implements MySession {
@JndiInject("java:/TransactionManager")
private javax.transaction.TransactionManager tm;
...
}
一些应用程序可能感兴趣的是获取一个引用到J2EE JTA事务管理服务.很多应用程序服务存储一个引用到这个服务在全局JNDI中.在这种情况下,我们使用@JndiInjected注释进入到会话Bean的字段直接的引用事务管理.现在我们定义了我们自定义的注入注释并且我们定义了怎样使用它,我们需要实现拦截器类的代码实现它的行为:
package com.titan.interceptors;
import java.lang.reflect.*;
import com.titan.annotations.JndiInjected;
import javax.ejb.*;
import javax.naming.*;
import javax.interceptor.*;
import javax.annotation.*;
public class JndiInjector
{
@PostConstruct
public void jndiInject(InvocationContext invocation) {
Object target = invocation.getTarget( );
Field[] fields = target.getClass().getDeclaredFields( );
Method[] methods = target.getClass().getDeclaredMethods( );
// find all @JndiInjected
fields/methods and set them
try {
InitialContext ctx = new InitialContext( );
for (Method method : methods) {
JndiInjected inject = method.getAnnotation(JndiInjected.class);
if (inject != null) {
Object obj = ctx.lookup(inject.value( ));
method.setAccessible(true);
method.invoke(target, obj);
}
}
for (Field field : fields) {
JndiInjected inject = field.getAnnotation(JndiInjected.class);
if (inject != null) {
Object obj = ctx.lookup(inject.value( ));
field.setAccessible(true);
field.set(target, obj);
}
}
invocation.proceed( );
} catch (Exception ex) {
throw new EJBException
("Failed to execute @JndiInjected", ex);
}
}
}
使用@javax.annotation.PostConstruct注释的jndiInject( )方法,告诉EJB容器JndiInjector拦截器感兴趣的是拦截指定的EJB回调.方法开始通过获取一个引用到组件实例它截取.通过反射来查找@JndiInjected对象的所有方法和字段.查找引用的JNDI名字,并且初始化目标组件实例的字段或方法.注意这是在try/catch 块中来做的.当拦截一个回调方法,你可以不用抛出检查异常:因此,所有的检查异常必需被捕获和包装在一个EJBException.
现在拦截器类已经被实现,我们可以应用拦截器到我们的组件当中:
<ejb-jar>
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>com.titan.interceptors.JndiInjector
</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
</ejb-jar>
这个例子中一个特别有趣而且显著的事情是你可以使用EJB拦截器作为一个框架为你写的自定义注释增加你想要的行为到EJB中.默认的拦截器,通过XML,给你一个简洁,简单的应用拦截器的实现行为在注释中.最后,这种自定义的行为是轻便的并且可以用在任意厂商来实现.不仅仅是EJB3.0容易使用,此外,最终还要易于扩展.
分享到:
- 2009-04-25 14:52
- 浏览 934
- 评论(0)
- 论坛回复 / 浏览 (0 / 2513)
- 查看更多
相关推荐
- **拦截器**: 讨论拦截器的作用及其在会话Bean中的实现方式。 - **依赖注入**: 深入了解依赖注入的概念,并展示在EJB中如何利用该特性。 #### 五、消息驱动Bean(Message Driven Bean) - **概念简介**: 消息驱动...
### EJB 3.0 中文版教程知识点总结 #### 1. 教程适用人群与背景 - **目标读者**:本教程旨在为具备Java基础的初学者提供EJB 3.0的学习资料,无需预先学习EJB 2.0。 - **技术变迁**:随着EJB 3.0的发展,EJB 2.0的...
**2.10 拦截器(INTERCEPTOR)** 用于在方法调用前后执行特定代码,例如日志记录或性能监控。 **2.11 依赖注入(DEPENDENCY INJECTION)** 依赖注入是一种设计模式,用于自动管理组件间的依赖关系,提高代码的可测试...
拦截器是EJB3.0中的另一个强大功能,它们允许在方法调用前后插入自定义逻辑。`Interceptor`示例解释了如何创建自定义拦截器,并演示了在哪些操作(如调用、事务、生命周期方法等)中可以插入拦截。 #### 2.5 `...
此外,还探讨了会话Bean的生命周期管理、JNDI名称的修改、拦截器的使用、依赖注入和定时服务等功能,这些都是EJB3.0的重要特性。 #### 消息驱动Bean(Message Driven Bean) 消息驱动Bean是EJB3.0中用于处理异步消息...
此外,还探讨了两种会话Bean的区别、如何修改其JNDI名称、生命周期管理,以及拦截器和依赖注入等高级特性。定时服务和安全服务也是重点讨论的内容,包括如何自定义安全域。 ### 消息驱动Bean(Message Driven Bean) ...
- **拦截器**: 解释如何使用拦截器来增强会话Bean的功能。 - **依赖注入**: 展示如何利用依赖注入来简化代码编写。 - **定时服务**: 探索EJB 3.0 中的定时服务功能。 - **安全服务**: 讨论EJB 3.0 安全框架的基本...
- 讲解拦截器的概念及其在EJB3.0中的应用场景。 - 如何编写和配置拦截器。 - **依赖注入 (Dependency Injection)**: - 介绍依赖注入的基本原理和技术实现。 - 如何在EJB3.0中利用注解自动完成依赖注入。 - **...
**生命周期** - 从创建到销毁的过程,包括初始化、激活和钝化等阶段。 ##### 4. **拦截器** - 用于增强Bean的方法行为,类似于AOP(面向切面编程)。 ##### 5. **依赖注入** - 通过注解(如`@EJB`、`@Inject`...