0
点赞
收藏
分享

微信扫一扫

如何让一个类在配置文件信息加载后,最先实例化

前程有光 2021-09-26 阅读 40

业务场景:

最近在实现 一个自动刷新spirngboot配置信息的第三方包时,需要在所有bean实例化之前改变spring环境的属性,这样才能在bean实例化之前获取到已经被第三方包改变的最新的配置信息。

但是,第三方包相关的bean,有可能在需要注入配置信息的bean之后才能被实例化,这样甚至会影响正常bean的创建。

所以需要让第三方bean优先于其他bean去实例化,实例化之后,spring的环境对象创建好之后,去更改配置信息。

思考方案:

1.将业务bean的作用域改为非单例

我们知道spring容器启动的时候,只会先去加载单例的bean,其他bean则不会去实例化。改为非单例之后,单例bean肯定在这些业务bean之前实例化。

缺点:

侵入性太强

1.多例的话,浪费性能
2.自定义bean的话,每个需要刷新的bean都需要打上自定义bean注解。有点小麻烦
3.并且对引用者来说侵入性太强了,影响太大

所以这里不推荐这种,还是继续往提前第三方bean的实例化方向思考。

2.第三方bean实现BeanDefinitionRegistryPostProcessor接口。

在spring容器中,会优先实例化BeanDefinitionRegistryPostProcessor类的bean,并调用postProcessBeanDefinitionRegistry()和postProcessBeanFactory()这个方法

但是由于我们依赖了spring环境Environment对象,而这个由于实例化太靠前,Environment还未注册进ioc容器中,导致业务代码无法从Environment获取重要的配置信息

所以,这种也拉稀了。

3.第三方bean实现LoadTimeWeaverAware接口

观察ioc 所有bean实例化的入口方法
finishBeanFactoryInitialization()

仔细看,发现在所有单例bean实例化之前,他会获取LoadTimeWeaverAware所有实现类的beanName,并且进行getBean(),触发实例化。

所以这里是一个完美的切入时间.

==最终采取这种方式,既能在第三方bean实例化的时候注入Envirment对象,进行使用,又能在其他正常bean实例化之前,进行配置信息的修改。==

举报

相关推荐

0 条评论