[英]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.