我有一些弹簧组件:
@Component
@ConditionalOnBean(value={JdbcTemplate.class})
public class DictionaryHandler implements Handler {
private final JdbcTemplate jdbcTemplate;
@Autowired
public DictionaryHandler(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//some methods
}
但是,我的bean没有创建,它没有进入构造函数。但为什么? Bean JdbcTemplate
存在,但我的bean没有创建。
条件是否起作用?如果缺少DictionaryHandler
,我不想创建JdbcTemplate
。没有这个,我会得到一个错误。
答案 0 :(得分:2)
您仅应在自动配置类上使用@ConditionalOnBean
(否则未指定顺序)
该条件只能匹配到目前为止应用程序上下文已处理的bean定义,因此,强烈建议仅在自动配置类上使用此条件。如果候选bean可能是由另一种自动配置创建的,请确保使用此条件的豆在此之后运行。
由于您的JdbcTemplate
bean是在JdbcTemplateAutoConfiguration
类中定义的,因此我假设JdbcTemplateAutoConfiguration
被标记为@Configuration
。
在这种情况下,您可以通过config来确保bean的实例化:
@Configuration
@AutoConfigureAfter(JdbcTemplateAutoConfiguration.class)
public class DicationaryHandlerConfiguration {
@Bean
@ConditionalOnBean(JdbcTemplate.class)
public DictionaryHandler handler(JdbcTemplate jdbcTemplate) {
return new DictionaryHandler(jdbcTemplate)
}
}
public class DictionaryHandler implements Handler {
private final JdbcTemplate jdbcTemplate;
public DictionaryHandler(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//some methods
}
答案 1 :(得分:1)
来自Annotation Type ConditionalOnBean:
该条件只能匹配到目前为止应用程序上下文已处理的bean定义,因此,强烈建议仅在自动配置类上使用此条件。如果候选bean可能是由另一种自动配置创建的,请确保使用此条件的候选bean在之后运行。
在您的情况下,问题是在处理配置类之前尝试创建DictionaryHandler
bean,并且考虑到JdbcTemplate
bean尚未位于DI容器中,因此您的DictionaryHandler
尚未存在被实例化。
一种解决方法是在与DictionaryHandler
相同的配置类中初始化JdbcTemplate
。
另外,您可以使用其他配置类,但必须使用@DependsOn
注释。
一个例子:
@Component
@ConditionalOnBean(name = "bean1")
class AnotherBean {
}
@Configuration
class Config {
@Bean
public Object bean1() {
return new Object();
}
}
在上一个示例中,AnotherBean
不会被创建,但是会这样:
@Configuration
class Config {
@Bean
public Object bean1() {
return new Object();
}
@Bean
@ConditionalOnBean(name = "bean1")
public AnotherBean anotherBean() {
return new AnotherBean();
}
}
答案 2 :(得分:1)
查看ConditionalOnBean的文档。它运行一次,并且如果尚未创建所需的Bean,则不会触发。 Bean创建的顺序很重要。您可以尝试使用@Order批注来降低组件的优先级,或者增加包含JdbcTemplate bean的配置/组件类的优先级。