Rob*_*anu 9 java spring dependency-injection guice
使用基于Spring的XML配置时,可以轻松地修饰同一接口的多个实现并指定顺序.例如,日志记录服务包装了一个包装实际服务的事务服务.
如何使用javax.inject注释实现相同的目标?
您可以@Named一起使用@Inject来指定要注入的bean.
注入服务的一个简单示例:
public class ServiceTest {
@Inject
@Named("transactionDecorator")
private Service service;
}
Run Code Online (Sandbox Code Playgroud)
和相应的事务装饰器类:
@org.springframework.stereotype.Service("transactionDecorator")
public class ServiceDecoratorTransactionSupport extends ServiceDecorator {
@Inject
@Named("serviceBean")
public ServiceDecoratorTransactionSupport(Service service) {
super(service);
}
}
Run Code Online (Sandbox Code Playgroud)
这会将您的配置暴露给您的代码,因此我建议您在@Configuration类中进行装饰逻辑并注释例如日志服务@Primary.使用这种方法,您的测试类可以看起来像这样:
public class ServiceTest {
@Inject
private Service service;
Run Code Online (Sandbox Code Playgroud)
和配置类:
@Configuration
public class DecoratorConfig {
@Bean
@Primary
public ServiceDecorator serviceDecoratorSecurity() {
return new ServiceDecoratorSecuritySupport(
serviceDecoratorTransactionSupport());
}
@Bean
public ServiceDecorator serviceDecoratorTransactionSupport() {
return new ServiceDecoratorTransactionSupport(serviceBean());
}
@Bean
public Service serviceBean() {
return new ServiceImpl(serviceRepositoryEverythingOkayStub());
}
@Bean
public ServiceRepository serviceRepositoryEverythingOkayStub() {
return new ServiceRepositoryEverythingOkStub();
}
}
Run Code Online (Sandbox Code Playgroud)
我的第二个示例没有公开有关将返回哪个实现的任何细节,但它取决于几个Spring特定的类.
您也可以将两种解决方案结合起来.例如@Primary,在装饰器上使用Spring的注释,让Spring将这个装饰器注入给定类型的实例中.
@Service
@Primary
public class ServiceDecoratorSecuritySupport extends ServiceDecorator {
}
Run Code Online (Sandbox Code Playgroud)
这是您通常使用 AOP 来完成的事情,而不是手动编写和包装实现(并不是说您不能这样做)。
对于带有 Guice 的 AOP,您需要创建一个事务MethodInterceptor和一个日志记录MethodInterceptor,然后用于bindInterceptor(Matcher, Matcher, MethodInterceptor)设置应拦截哪些类型和方法。第一个Matcher匹配要拦截的类型,第二个匹配要拦截的方法。可以是Matchers.any(),匹配类型或方法上的特定注释(@Transactional例如)或您想要的任何内容。然后匹配方法被拦截并自动处理。基本上,装饰器模式的样板代码少了很多。
要手动执行此操作,一种方法是:
class ServiceModule extends PrivateModule {
@Override protected void configure() {
bind(Service.class).annotatedWith(Real.class).to(RealService.class);
}
@Provides @Exposed
protected Service provideService(@Real Service service) {
return new LoggingService(new TransactionalService(service));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7739 次 |
| 最近记录: |