我有一个配置类,它根据一个非常简单的条件(检查application.properties中的属性值(注册bean。配置类和条件如下:
@Configuration
@Conditional(DatabaseConfigurationCondition.class)
@ComponentScan(basePackageClasses = DBConfigComponents.class)
public class DatabaseConfigurationLoader {
@Bean
public DatabaseConfigurationRepository databaseConfigurationRepository() {
return new DatabaseConfigurationRepository();
}
}
和
public class DatabaseConfigurationCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("configuration.type").contains("db");
}
}
除了在这个配置类中注册的bean之外,我还有扫描其他组件的组件扫描。当条件不满足时,我希望配置类中定义的bean不被注册(碰巧是这样(,但我也希望其他用@Component
(或@Repository
、@Service
等(注释的类和DBConfigComponents.class
标记接口在同一文件夹中的类不被注册,这是不会发生的。被扫描的bean总是被注册的,无论条件是否满足。
当我把@Conditional(DatabaseConfigurationCondition.class)
放在每个带@Component
注释的类上时,它工作正常,但我不想把它单独放在每个类上。
有什么建议吗?
幸运的是,我设法解决了这个问题。在我的案例中,问题是我在其他Maven模块的其他配置类中放置了另一个@ComponentScan
注释,而不是以任何属性为条件。与DBConfigComponents
标记接口在同一个包中的组件实际上是由其他配置类扫描的。
@ComponentScan
的工作方式是在包级别上。尽管在不同的Maven模块中,两个配置类都在同一个包中。CCD_ 10与CCD_。不需要将@Conditional
单独放置在每个组件上。
实现这一点的最佳方法是不要使用@Component/@Service和@Repository注释来对这些bean进行注释。相反,您应该将这些作为您所设置的配置(DatabaseConfigurationLoader
(的一部分返回。请参阅下面的示例。
@Configuration
@Conditional(DatabaseConfigurationCondition.class)
public class DatabaseConfigurationLoader {
@Bean
public DatabaseConfigurationRepository databaseConfigurationRepository() {
return new DatabaseConfigurationRepository();
}
@Bean
public SomeService someService() {
return new SomeService();
}
@Bean
public SomeComponent someComponent() {
return new SomeComponent();
}
}
注意:通常
@Configuration
和@Conditional
用于要包含在春季启动应用程序中的库。这样的库不应该与spring-boot应用程序共享同一个包。因此,它们不应该被@ComponentScan
注释拾取。来自库的bean不应该使用@Component
/@Service
/@Repository
注释进行注释。Spring建议使用自动配置。看见https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html&https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
无需实现Condition接口,需要使用'@ConditionalOnProperty'注释:
@Configuration
@ComponentScan(basePackageClasses = DBConfigComponents.class)
@ConditionalOnProperty(name = "configuration.type", havingValue = "db")
public class DatabaseConfigurationLoader {
@Bean
public DatabaseConfigurationRepository databaseConfigurationRepository() {
return new DatabaseConfigurationRepository();
}
}
您可以根据需要使用"prefix"而不是"havingValue"。