Spring:如何使服务以 PlatformTransactionManager bean 的可用性为条件?
Spring: How to make a service conditional on the availability of a PlatformTransactionManager bean?
我有一个 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
bean 可用,因为当我 @Autowire
在我的测试中使用 PlatformTransactionManager
而不是 FooService
.
有趣的是,我还尝试用 WebClient.Builder
替换 PlatformTransactionManager
,最后一切正常。 PlatformTransactionManager
有什么特别之处?
如何编写 FooService
以便它在 PlatformTransactionManager
bean 可用时工作,并且不阻止没有此类 bean 可用的应用程序启动?
添加 @AutoConfigureOrder
注释以确保在 Spring Boot:
注册事务管理器 bean 之后处理您的自动配置 class
@Configuration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public class FooAutoConfiguration {
}
我有一个 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
bean 可用,因为当我 @Autowire
在我的测试中使用 PlatformTransactionManager
而不是 FooService
.
有趣的是,我还尝试用 WebClient.Builder
替换 PlatformTransactionManager
,最后一切正常。 PlatformTransactionManager
有什么特别之处?
如何编写 FooService
以便它在 PlatformTransactionManager
bean 可用时工作,并且不阻止没有此类 bean 可用的应用程序启动?
添加 @AutoConfigureOrder
注释以确保在 Spring Boot:
@Configuration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public class FooAutoConfiguration {
}