我正在编写一个Spring Boot Starter,我想实现在Spring IOC中动态创建bean注入,并且可以使@ConditionalOnMissingBean在不创建默认bean的情况下生效。
我试图直接在配置类中编织beanfactory,并通过ConfigurableBeanFactory调用registerSingleton方法来动态创建bean,但是结果是错误的,@ ConditionalOnMissingBean无效。 @Bean可以,这应该与春季启动扫描@Configuration类和相应的@Bean方法有关,但是@Bean无法实现Bean的动态创建,因为我需要的Bean是根据配置的内容生成的文件,数量不确定,内容不确定。
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
while (iterator.hasNext()) {
// Generate a bean based on the configuration
...
SpringBean bean = ...
configurableBeanFactory.registerSingleton(SpringBeanName, bean);
}
我希望如果动态创建bean,@ConditionalOnMissingBean仍然会生效。
答案 0 :(得分:1)
如API documentation中所述:
@Conditional批注可以通过以下任何一种方式使用:
- 作为直接或间接使用@Component注释的任何类的类型级别注释,包括@Configuration类
- 作为元注释,目的是组成自定义构造型注释
- 作为任何@Bean方法上的方法级注释
这意味着它对启动后在ApplicationContext
中注册的动态创建的bean无效。
因此,当您想实现类似的行为时,请尝试检查bean是否存在于ApplicationContext中,如下所示:
@Autowired
private ApplicationContext context;
...
context.getBeansOfType(YourType.class).isEmpty()
要摆脱该bean的默认配置时,需要排除它。有两种方法可以实现这一目标。通过将其定义为@SpringBootApplication(exclude = SomeConfig.class)
来排除定义该bean的整个配置文件,或者在@ComponentScan上实现自己的排除过滤器。