BeanFactory创建流程及继承体系
Ioc容器初始化主体流程之BeanFactory及容器继承体系
文章内容输出来源:拉勾Java高薪训练营
首先我们来看这么一张图,可以看到容器的顶级接口是BeanFactory,但是BeanFactory接口却并没有多少方法,这也是Spring的精妙之处,通过继承顶级接口来各自完成各自的事情,各自分工。而ApplicaitonContext接口是容器的高级接口。它的主要实现类就是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者从类路径加载配置资源,后者从系统文件加载配置文件。
Spring应用上下文,官方又称IOC容器,主要作用是管理创建Bean.那么首先了解一下Bean的生命周期。

那么通过搭建好的spring源码环境来启动测试用例来分析一下Bean的创建流程。首先一个 简单测试类:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
System.out.println(lagouBean);
这个代码的作用就是从类路径加载xml文件,生成一个Bean。我们主要是debug来看一下执行流程。
/**
* 构造函数
*/
public LagouBean(){
System.out.println("LagouBean 构造器...");
}
在构造函数处打一个断点,来看一下调用栈进入了哪一个方法:
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
可以看到它首先进入了AbstractApplicationContext的refresh方法,然后再refresh方法里调用finishBeanFactoryInitialization(beanFactory);
TIPS:记住这个refresh方法,后面要考。
接下来看初始化Bean的断点:
/**
* InitializingBean 接口实现
*/
public void afterPropertiesSet() throws Exception {
System.out.println("LagouBean afterPropertiesSet...");
}
调用栈和上面一样,初始化依然在refresh方法的finishBeanFactoryInitialization(beanFactory);执行。
那么这个refresh方法到底有什么呢?我们来看看
在ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");打一个断点。
在进入一个静态方法后跳出,然后继续进入,
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 初始化父类
super(parent);
setConfigLocations(configLocations);
// 重点。刷新方法
if (refresh) {
refresh();
}
}
进入到一个构造方法,重点跳进refresh方法。如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
// 对象锁 fresh() 和 close() 都会用到锁
synchronized (this.startupShutdownMonitor) {
// 刷新前的处理
prepareRefresh();
// 获取beanfactory;默认实现是DefaultListableBeanFactory加载BeanDefition 并注册到 BeanDefitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// beanfactory的预备工作,比如context的类加载器
prepareBeanFactory(beanFactory);
try {
// beanfactory准备工作完成后的后置处理工作
postProcessBeanFactory(beanFactory);
// 实例化并调用实现了了BeanFactoryPostProcessor接口的bean
invokeBeanFactoryPostProcessors(beanFactory);
// 注册beanPostProcessor在创建bean的前后执行
registerBeanPostProcessors(beanFactory);
// 国际化
initMessageSource();
// 初始化事件派发器
initApplicationEventMulticaster();
// 子类重写这个方法可以自定义容器刷新逻辑.
onRefresh();
// 检查监听器并注册.
registerListeners();
// 这是重点。初始化非懒加载 的单例bean,
// 初始化创建非懒加载实例
// 填充属性
// 初始化方法调用
// 调用BeanPostProecessor对实例bean进行后置处理
finishBeanFactoryInitialization(beanFactory);
// 完成context的刷新
finishRefresh();
}
// 异常部分省略
接下来讲讲是如何获取一个BeanFactory的。
进入到refresh方法的ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();这一行代码,断点进去。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新beanfactory
refreshBeanFactory();
// 返回beanfactory
return getBeanFactory();
}
进入到第一步刷新方法中
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果有了工厂
if (hasBeanFactory()) {
// 销毁
destroyBeans();
// 关闭
closeBeanFactory();
}
try {
// 创建一个beanfactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 设置序列号
beanFactory.setSerializationId(getId());
// 自定义
customizeBeanFactory(beanFactory);
// 加载bean定义
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}


浙公网安备 33010602011771号