java - 装饰器模式和@Inject

标签 java spring dependency-injection guice

在使用Spring基于XML的配置时,很容易装饰同一个接口(interface)的多个实现并指定顺序。例如,日志记录服务包装了交易服务,而交易服务又包装了实际服务。

如何使用 javax.inject 注释实现同样的效果?

最佳答案

您可以使用 @Named@Inject 来指定要注入(inject)的 bean。

一个带有注入(inject)服务的简单示例:

public class ServiceTest {

    @Inject
    @Named("transactionDecorator")
    private Service service;
}

以及对应的事务装饰器类:

@org.springframework.stereotype.Service("transactionDecorator")
public class ServiceDecoratorTransactionSupport extends ServiceDecorator {

    @Inject
    @Named("serviceBean")
    public ServiceDecoratorTransactionSupport(Service service) {
        super(service);
    }
}

这会将您的配置公开到您的代码中,因此我建议在 @Configuration 类中执行装饰逻辑,并使用 @Primary 注释例如日志记录服务。使用这种方法,您的测试类可能如下所示:

public class ServiceTest {

    @Inject
    private Service service;

和配置类:

@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();
    }
}

我的第二个示例没有公开有关将返回哪个实现的任何细节,但它取决于几个 Spring 特定类。

您也可以结合使用这两种解决方案。例如,在装饰器上使用 Spring 的 @Primary 注释,让 Spring 将此装饰器注入(inject)给定类型的实例。

@Service
@Primary
public class ServiceDecoratorSecuritySupport extends ServiceDecorator {
}

关于java - 装饰器模式和@Inject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3149137/

相关文章:

java - 如何将对象传递给 UnitTest 类中被测试的类?

android - Dagger2 - "is not a framework type."错误

c# - 在单元测试中使用伪造接口(interface)中未定义的方法

java - 如何将json数据发送到splunk HEC或splunk enterprise

java - 在不使用 arrays.sort 的情况下按升序对随机数组进行排序

java - HashSet 包含子字符串

java - VerticalLayout 中的多个 CssLayout

java - 如何使用 HQL(Hibernate 查询语言)获取列的最后一个值

spring - 在 DELETE 请求的正文中传递数据

.net - Windsor - 从容器中拉出 transient 对象