У меня есть FooService
, который я хотел бы быть доступным, только когда доступен PlatformTransactionManager
.
Если я определю свой сервис таким образом, а PlatformTransactionManager
не будет доступен, то мое приложение будетне удалось запустить:
@Service
public class FooService {
public FooService(final PlatformTransactionManager txManager) { ... }
...
}
Я хотел использовать ConditionalOnBean
, который должен аннотировать только классы автоматической конфигурации.Я реорганизовал свой код следующим образом:
@Configuration
public class FooAutoConfiguration {
@Bean
@ConditionalOnBean(PlatformTransactionManager.class)
public FooService fooService(final PlatformTransactionManager txManager) {
return new FooService(txManager);
}
}
public class FooService {
public FooService(final BarBean bar) { ... }
...
}
Я написал следующий тест для FooService
:
@ExtendWith(SpringExtension.class)
@Import(FooAutoConfiguration.class)
public class FooServiceTest {
@Autowired
private FooService fooService;
@Test
public void test() {
System.out.println("fooService = " + fooService);
}
}
Но я получаю следующее исключение при попытке его запустить:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.acme.FooServiceTest': Unsatisfied dependency expressed through field 'fooService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.acme.FooService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
(...)
Однако я знаю, что доступен компонент PlatformTransactionManager
, потому что тест выполняется нормально, когда в моем тесте я @Autowire
a PlatformTransactionManager
вместо FooService
.
Интересно, что я также попытался заменить PlatformTransactionManager
на WebClient.Builder
, и все в итоге работает как надо.Что такого особенного в PlatformTransactionManager
?
Как я могу написать FooService
, чтобы он работал, когда доступен компонент PlatformTransactionManager
, и не препятствовал запуску приложений, в которых такой компонент недоступен?