spring - ApplicationContext registerBean自动装配失败,但getBean在Spring 5中工作 [英] spring - ApplicationContext registerBean autowiring fails but getBean works in Spring 5
问题描述
我正在使用一个使用动态bean注册的配置类:
I'm using a configuration class that uses dynamic bean registration:
@Configuration
public class ConfigClass {
@Autowired
private GenericApplicationContext applicationContext;
@PostConstruct
private void init() {
System.out.println("init");
applicationContext.registerBean("exService", ExecutorService.class, () -> Executors.newFixedThreadPool(10), bd -> bd.setAutowireCandidate(true));
System.out.println("init done");
}
}
如果我尝试自动装配bean,应用程序启动失败错误 com.example.DemoApplication中的字段exService需要找不到找不到的类型为'java.util.concurrent.ExecutorService'的bean。
If I try to autowire the bean, application startup fails with error Field exService in com.example.DemoApplication required a bean of type 'java.util.concurrent.ExecutorService' that could not be found.
从日志中我可以看到,在错误发生前没有调用config类上的init方法,因为没有打印出两个系统输出语句。
From the logs I can see that the init method on config class wasn't called before the error as the two system out statements were not printed out.
但是,当我使用 applicationContext.getBean(ExecutorService.class)
时,它确实可以正常工作。
However, when I use applicationContext.getBean(ExecutorService.class)
it does work without any issues.
无论如何我可以把bean送到Autowire?
Anyway I can get the bean to Autowire?
我故意不使用 @Bean
注释因为我需要根据某些条件动态注册bean。
I'm deliberately not using the @Bean
annotation because I need to register the beans dynamically based on certain conditions.
推荐答案
这可能是因为你正在注册你的bean上下文初始化阶段。如果你的目标bean在 ConfigClass
@PostConstruct $ c之前初始化并自动连接
ExecutorService
只有没有可用的bean才调用$ c>。
It could be because you are registering your bean in the middle of the context initialization phase. If your target bean initializes and auto-wires ExecutorService
before ConfigClass
@PostConstruct
is invoked there simply is no bean available.
你可以尝试强制初始化顺序:
You can try forcing the initialization order:
@Component
@DependsOn("configClass")
public class MyComponent
@Autowired
private ExecutorService executorService;
然而,使用 BeanFactoryPostProcessor $注册bean定义会更清晰c $ c> with
BeanDefinitionBuilder
:
However it would be cleaner to register a bean definition using BeanFactoryPostProcessor
with BeanDefinitionBuilder
:
@Component
public class MyBeanRegistration implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
BeanDefinitionRegistry reg = (BeanDefinitionRegistry) bf;
reg.registerBeanDefinition("exService",
BeanDefinitionBuilder
.rootBeanDefinition(ExecutorService.class)
.setFactoryMethod("newWorkStealingPool")
.getBeanDefinition());
}
}
这篇关于spring - ApplicationContext registerBean自动装配失败,但getBean在Spring 5中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!