Вы можете использовать @Named
вместе с @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 внедрить этот декоратор в экземпляр данного типа.
@Service
@Primary
public class ServiceDecoratorSecuritySupport extends ServiceDecorator {
}