spring - ApplicationContext registerBean自动装配失败,但getBean在Spring 5中工作

are*_*res 4 java spring autowired spring-boot

我正在使用一个使用动态bean注册的配置类:

@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");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试自动装配bean,应用程序启动会失败并显示错误 Field exService in com.example.DemoApplication required a bean of type 'java.util.concurrent.ExecutorService' that could not be found.

从日志中我可以看到,在错误之前没有调用config类的init方法,因为没有打印出两个系统输出语句.

但是,当我使用applicationContext.getBean(ExecutorService.class)它确实没有任何问题.

无论如何,我可以把豆子送到Autowire?

我故意不使用@Bean注释,因为我需要根据某些条件动态注册bean.

Kar*_*cki 9

可能是因为您正在上下文初始化阶段注册bean.如果你的目标bean ExecutorServiceConfigClass @PostConstruct调用之前初始化并且自动连线,那么就没有可用的bean.

您可以尝试强制初始化顺序:

@Component
@DependsOn("configClass")
public class MyComponent

  @Autowired
  private ExecutorService executorService;
Run Code Online (Sandbox Code Playgroud)

但是使用BeanFactoryPostProcessorwith 注册bean定义会更清晰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());
  }

}
Run Code Online (Sandbox Code Playgroud)