背景:
现在需要在某个 ZooService 中获取环境上下文 ApplicationContext ,然后在 afterPropertiesSet 中用 ApplicationContext 获取某个接口 Animal 的所有实现类(Tiger、Lion、…)并保存到 ZooService 中的成员变量 animals 中。
疑惑:
根据网上资料显示,afterPropertiesSet 会在一个 bean 初始化完成后调用。会不会存在一种情况,就是 ZooService 完成初始化,而 Animal 的实现类还没有完成初始化,此时触发 ZooService 的 afterPropertiesSet 方法,用 ApplicationContext 获取某个接口 Animal 的所有实现类,会出现部分 Animal 实现类(如Tiger)还没初始化的情况 ,甚至有可能所有 Animal 的实现类都获取不到。
探究:
搞清楚 afterpropertiesset 是不是在容器所有 bean 都初始化完毕才进行
结论:
afterPropertiesSet 并不是在所有 bean 初始化完成后才进行,它在当前 bean 实例化并注入好依赖后即执行。
但我们依然能达到期望的结果,跟进 applicationContext.getBeansOfType() 源码一探,发现它的执行逻辑如下:
1、从 beanDefinitions 中获取符合 type 类型的所有 beanName
2、循环1得到的 beanNames,逐个调用他们的 getBean 方法
由上可知,就算案例中我们的 ZooService 先初始化,而此时 Tiger 类还没初始化,在调用 getBeansOfType 方法时也会把指定 type 的未实例化的 bean 都实例化一遍,那么也就不存在我们担心的上下文获取实现类失败的情况。