与EJB2.1相比,EJB3.0规范引入了两个重要概念:依赖注入(DI:Dependency Injection)和截获器(Interceptor),本文首先介绍了这两个概念并给出相关示例,然后分析了EJB3.0规范在这两方面的不足之处,最终深入探讨了WebLogic Server 10对它们的支持和扩展。
2 依赖注入
2.1 基本概念
依赖注入是从开源社区的一些著名轻量级容器(如Spring、Pico container)中所发展出来的概念,其主要思想就是由容器而不是对象本身来负责处理对象之间的依赖关系。与传统的服务定位器相比,依赖注入具有易测试、弱侵入性等优点,这也就是为什么在最新的Java EE 5规范中引入它的原因。
当前应用服务器可使用Pitchfork实现Java EE 5中的依赖注入,标注处理以及EJB3.0中的截获器。
在Spring容器中支持Java EE 5的标注
5.2 WebLogic Server 10 EJB3.0容器的架构
WebLogic Server 10完全支持Java EE 5和EJB3.0,其EJB3.0 容器是基于Pitchfork来实现依赖注入与截获器的,而Pitchfork又利用了Spring的依赖注入和AOP。此时,WebLogic Server 10的用户有两种选择:
使用EJB3.0标准模型: EJB bean实例由EJB容器创建,然后由Pitchfork实施Java EE 5 的依赖注入和截获器,这是WebLogic Server 10的缺省配置。
使用Spring扩展模型:EJB bean实例由Spring容器创建并实施Spring的依赖注入,然后由Pitchfork实施Java EE 5的依赖注入,EJB3.0截获器和Spring AOP。
@Stateless(name="AccountManagementBean")
@Remote({examples.AccountManagement.class})
public class AccountManagementBean
{
public AccountManagementBean() {}
@Interceptors({examples.JEEInterceptor.class})
public boolean doBusiness(String account) {
System.out.println("I am doing business " + account);
return true;
}
}
(2) 开发一个JEE interceptor
public class JEEInterceptor {
@AroundInvoke
private Object intercept(InvocationContext inv) throws Exception{
System.out.println("I am in JEEInterceptor.intercept()");
return inv.proceed();
}
}
(3) 开发一个Advice
public class SimpleAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("I am in Spring AOP interceptor");
return invocation.proceed();
}
}
(4) 开发一个Pointcut
public class SimpleStaticPointcut extends StaticMethodMatcherPointcut {
public boolean matches(Method method, Class cls) {
return "doBusiness".equals(method.getName());
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
public boolean matches(Class cls) {
return AccountManagementBean.class.isAssignableFrom(cls);
}
};
}
}
(5) 开发一个AspectJ Aspect
@Aspect
public class Aspects {
@Around("execution(* examples.AccountManagementBean.doBusiness(..))")
public Object around(ProceedingJoinPoint pjp) {
System.out.println(“I am in AspectJ aspect);
Object retVal = null;
try {
retVal = pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
return retVal;
}
}
依赖注入和截获器的引入,使得EJB3.0克服了很多EJB2.1的缺点,但与开源社区中流行的轻量级容器相比,EJB3.0无论是在依赖注入的范围还是在AOP的易用性方面都还存在一定的不足。而最近BEA所推出的WebLogic Server 10不但完全支持EJB3.0,而且对其进行了有效扩展,这使得一方面可以充分利用在开源社区中出于领导地位的Spring在依赖注入和AOP方面的强大能力,另一方面又紧密依托WebLogic Server 10在事务、安全、集群方面领先的技术,从而为EJB3.0用户开发出易维护、可扩展、高效率的企业应用程序打下坚实的基础。