| |
EJB 3.0+Aspect实现声明性编程初步 |
|
时间: 2005-11-19 来自:天极网 |
 |
|
|
三、 资源注入
EJB 3.0草案声明中允许资源经由@Resource注解来声明(这一决定定义在草案普通注解声明中)并且被容器注入进你的EJB。依赖性注入是一项技术-使用这种技术,一个对象外部的实体而不是显式地为该对象所创建的实体能够提供(注入)一个对象的依赖性。它有时被描述为好莱坞原则-这开玩笑似地意味着"不要给我们打电话,我们会给你打电话的"。
以TravelAgencyServiceImpl类为例-这个类为了持续性存储一些数据需要找到一个IFlightDAO接口的实现。传统地,这是经由一个工厂、singleton、服务定位器或一些另外的定制解决方案来实现的。其中,一个可能的解决方案看上去如下所示:
你已看到,这个实现包含创建一个特定的工厂类-它很可能读取存储在某处的配置信息以了解要创建IFlightDAO的实现方式。如果不是让服务显式地创建它的由容器所注入的依赖性,那么配置细节和对象创建将被代理到容器上。这允许一个应用程序中的组件能够被容易地连接到一起-用不同的配置并且消除大量老式的singleton和工厂代码。
该类的一个实现-它依赖于一个用JSR 250资源注解所声明的IFlightDAO的实现-可能看上去如下所示:
public class TravelAgencyServiceImpl implements ITravelAgencyService { @Resource(name = "flightDAO") public IFlightDAO flightDAO; public void bookTrip(long outboundFlightID, long returnFlightID, int seats) throws InsufficientSeatsException { reserveSeats(outboundFlightID, seats); reserveSeats(returnFlightID, seats); } } | 在这种情况下,容器将把一个命名为"flightDAO"的资源的正确实现提供给服务类。但是,如果你现在就想利用资源注入,而不是等待EJB 3.0发行版,又该如何呢?好,你可以采用一种轻量级的容器-它能够提供例如Spring或Pico Container的依赖性注入。然而,当前我还不了解存在一个轻量级的容器-它能够使用JSR 250资源注解以指定注入要求(尽管我非常盼望在这一方面出现一些)。
一种解决方案是使用方面来实现依赖性注入。如果你为此使用@Resource注解,那么你的实现将与EJB 3.0方式一致并且向前兼容EJB 3.0实现-而实现这并不是很困难的事情。下列列表显示用AspectJ创建的一个方面-它注入用@Resource注解所注解的字段:
@Aspect public class InjectionAspect { private DependencyManager manager = new DependencyManager(); @Before("get(@Resource * *.*)") public void beforeFieldAccesses(JoinPoint thisJoinPoint) throws IllegalArgumentException, IllegalAccessException { FieldSignature signature = (FieldSignature) thisJoinPoint.getSignature(); Resource injectAnnotation = signature.getField().getAnnotation(Resource.class); Object dependency = manager.resolveDependency(signature.getFieldType(),injectAnnotation.name()); signature.getField().set(thisJoinPoint.getThis(), dependency); } } | 这个简单方面所做的全部是,从一个属性文件(这个逻辑被封装在DependencyManager对象中)查询实现类并且在存取字段之前把它注入到用@Resource注解所注解的字段中。显然,这种实现不是完整的,但是它确实说明了你可以怎样以一种JSR 250兼容方式且不需采用EJB来提供资源注入。
|
|
|
|
|
|
|
|