繁体   English   中英

关于spring bean初始化的顺序

[英]about the order of spring bean initialing

我有一个由 rest 控制器使用的自定义 spring-boot 启动项目,自动配置类用于创建几个(根据 application.yml 中的配置值)存储上下文实例作为 spring 单例,所以我必须动态创建它们BeanFactoryAware 的 setBeanFactory 方法:


@Import(StorageContextProperties.class)
public class StorageAutoConfiguration implements BeanFactoryAware {

      ......
        
      @Override
      public void setBeanFactory(BeanFactory factory) throws BeansException {

         ......

         StorageContextProperties config = beanFactory.getBean(StorageContextProperties.class);

         config.getProfiles().stream().forEach(p ->  {

              ......

              ((SingletonBeanRegistry) beanFactory).registerSingleton(profile.name, instance);





问题是在控制器@autowired 事件之前没有调用该方法,所以它会抱怨没有 StorageContext 实例,我也尝试过 BeanFactoryPostProcessor 和 InitializingBean 接口,它们都不起作用。

但是,我注意到如果我只是将一些特殊的 @Bean 方法添加到自动配置类中,让我们说:

@Import(StorageContextProperties.class)
public class StorageAutoConfiguration implements BeanFactoryAware{

    @Bean
    public MethodValidationPostProcessor validationPostProcessor2() {
        return new MethodValidationPostProcessor();
    }
    

    ......

    @Override
    public void setBeanFactory(BeanFactory factory) throws BeansException {


然后setBeanFactory()会在controller之前被调用,看来spring需要MethodValidationPostProcessor实例,所以它创建了singleton bean的共享实例:StorageAutoConfiguration,同时创建了StorageContextProperties实例并调用了setBeanFactory()。

如果我在上面添加 @Bean 方法,代码就可以工作。 事情也以这种方式进行得很顺利,但我不喜欢这种风格,因为我实际上不需要 MethodValidationPostProcessor。

有没有优雅的(没有@Bean 方法)方法来实现它?

我的要求是:

在控制器创建事件之前。

1 创建 StorageContextProperties(它是 @Import 的 @ConfigurationProperties 类) 2 一些回调我可以调用 registerSingleton() 来创建我的 Storage Context 实例

谢谢!

[更新1]

我仍然找不到任何方法让它工作,但我将代码更改为:


@Configuration
@Import(StorageContextProperties.class)
@ConditionalOnProperty(prefix = "avalon.thiton.storage.config", name = "masterKey")
public class StorageAutoConfiguration implements BeanFactoryAware {

    private static Logger log = LoggerFactory.getLogger(StorageAutoConfiguration.class);

    @Bean
    @Order(Ordered.LOWEST_PRECEDENCE)
    @ConditionalOnMissingBean(MethodValidationPostProcessor.class)
    public MethodValidationPostProcessor placeholder() {
        return new MethodValidationPostProcessor();
    }

    ......

这让我感觉……好多了。

嗨,当我尝试使用 BeanFactoryAware 接口初始化自定义 bean 时,我遇到了类似的问题——@Configuration 注释类如下:

@Configuration
@EnableConfigurationProperties(SomeProps.class)
class MyConfiguration implements BeanFactoryAware {

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    ...
    ...
  }

  @Bean
  MyBean myBean(){
    return new MyBean();
  }
}

在需要 MyBean 并抛出 NoSuchBeanDefinitionException 之前,它没有运行此配置类代码。

为了解决这个问题,我将 BeanFactoryAware 接口更改为扩展 AbstractBeanFactoryAwareAdvisingPostProcessor ,如下所示:

@Configuration
@EnableConfigurationProperties(SomeProps.class)
class MyConfiguration extends AbstractBeanFactoryAwareAdvisingPostProcessor {

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    ...
    ...
  }

  @Bean
  MyBean myBean(){
    return new MyBean();
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM