现在开始分析prepareBeanFactory步骤,从注释上看了解,该方法得作用是:为当前使用的上下文准备beanFactory,主要包含如下几个步骤
- 设置容器的一些属性值
- 添加BPP(BeanPostProcessor的简称,往后都以BPP来替代)后置处理器
- ignoreDependencyInterface
- registerResolvableDependency
- 手动注册环境的单例Bean
主要介绍后面三点
- 手动注册环境的单例Bean
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
// 在DefaultSingletonBeanRegistry保存单例
super.registerSingleton(beanName, singletonObject);
// 添加进行DefaultListableBeanFactory中手动注册的单例Bean
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
if (!this.beanDefinitionMap.containsKey(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames.size() + 1);
updatedSingletons.addAll(this.manualSingletonNames);
updatedSingletons.add(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
if (!this.beanDefinitionMap.containsKey(beanName)) {
this.manualSingletonNames.add(beanName);
}
}
clearByTypeCache();
}
最终单例Bean还是保存在DefaultSingletonBeanRegistry
- registerResolvableDependency
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
源码就是在DefaultListableBeanFactory的resolvableDependencies(结构为Map)中添加对应的键值对,其作用为,如当其它地方需要注入ApplicationContext对象时,优先使用Value所指定的对象。当一个接口有很多实现类的时,在其他地方只使用@Autowired进行注入会报错。可以采用@Autowired和@Qualifier指定bean的名字一起使用。又或者直接在对应的实现类上添加该注解@Primary。如果只想使用@Autowired来进行注入,可以实现BFPP来重写对应的方法,可查看如下代码
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// k:指定依赖对象类型,v:具体的实例对象 registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
beanFactory.registerResolvableDependency(k,v);
}
}
- ignoreDependencyInterface
对该方法的解释可以参考该链接 https://www.jianshu.com/p/3c7e0608ff1f,针对文章里面说的相关demo也进行相关测试,如预期所料。