spring - ApplicationContext registerBean自动装配失败,但getBean在Spring 5中工作 [英] spring - ApplicationContext registerBean autowiring fails but getBean works in Spring 5

查看:1919
本文介绍了spring - ApplicationContext registerBean自动装配失败,但getBean在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 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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆