spring初始化过程也叫ioc容器初始化过程、bean生命周期。
1、从main函数开始
public static void main(String[] args) {
// 创建 ioc 容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取 bean
User user = (User) context.getBean("user");
user.test();
}
2、进入new ClassPathXmlApplicationContex()构造方法,看ioc容器的创建过程
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
// 获取xml文件并存储到String[] configLocations中
this.setConfigLocations(configLocations);
if (refresh) {
// 重点方法,功能较复杂,继续往下看
this.refresh();
}
}
3、进入AbstractRefreshableConfigApplicationContext类的this.setConfigLocations()方法,可以看到参数locations的内容如下图

把参数location解析完路径后放入string[] configLocations中,如下图

返回上一层ClassPathXmlApplicationContext构造方法
4、进入AbstractApplicationContext类的this.refresh()方法,该方法是重点
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
4.1、进入this.prepareRefresh()方法

看看this.getEnvironment()内容,jdk环境信息和转换器

继续看validateRequiredProperties()方法

继续进入AbstractPropertyResolver.validateRequiredProperties()


至此,this.prepareRefresh()方法解析完毕,总结下它的作用:
4.2、进入this.obtainFreshBeanFactory()方法

方法this.refreshBeanFactory()是重点,进入

创建DefaultListableBeanFactory对象,可以理解为就是ApplicationContext

方法this.loadBeanDefinitions(beanFactory)是重点,进入

创建XmlBeanDefinitionReader对象,用于解析xml文件中定义的bean

方法this.loadBeanDefinitions(beanDefinitionReader)是重点,进入

接下来是bean解析和保存的过程,一路进入到AbstractBeanDefinitionReader.loadBeanDefinitions(String location, Set<Resource> actualResources)方法

拿到resource[xml文件],进入this.loadBeanDefinitions(resources)方法,一路往下走,最终又会进入XmlBeanDefinitionReader.(EncodedResource encodedResource)方法

进入this.doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法,把resource解析为doc

进入this.registerBeanDefinitions(doc, resource)方法

进入documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource))方法

进入this.doRegisterBeanDefinitions(root)方法

进入this.parseBeanDefinitions(root, this.delegate)方法

进入this.parseDefaultElement(ele, delegate)方法

进入this.processBeanDefinition(ele, delegate)方法,将xml中的bean信息解析封装为BeanDefinition对象

进入BeanDefinitionReaderUtils.registerBeanDefinition()方法,将BeanDefinition对象注册到BeanFactory中

至此this.obtainFreshBeanFactory()方法方法解析完毕,总结它的作用:
4.3、进入this.prepareBeanFactory(beanFactory)方法

该方法作用,主要给beanFactory设置相关属性:
1、类加载器、类表达式解析器、属性编辑注册器
2、添加bean后处理器等
3、资源注册
4、注册默认的environment beans
4.4、this.postProcessBeanFactory(beanFactory)不用关注。
4.5、进入this.invokeBeanFactoryPostProcessors(beanFactory)方法
调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors

调用实现Ordered的BeanDefinitionRegistryPostProcessors

总结该方法作用:
4.6、进入this.registerBeanPostProcessors(beanFactory)方法

BeanPostProcessor与BeanFactoryPostProcessor很类似,也是存在优先级的,但BeanPostProcessor在处理完之后,并没有立即调用processor的方法,而是将一系列的BeanPostProcessor实体对象注册到BeanFactory中。在后面的初始化过程中会使用到这些Processor。
总结该方法作用:
4.7、 方法initMessageSource()是空方法,不用关注
4.8、进入initApplicationEventMulticaster()方法

总共该方法作用:
4.9、方法this.onRefresh()是空方法,不用关注
4.10、进入this.registerListeners()方法

总结该方法作用:
4.11、进入this.finishBeanFactoryInitialization(beanFactory)方法,该方法也是重点
该方法调用过程:【数据来源顶部链接】
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization()
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons()
org.springframework.beans.factory.support.AbstractBeanFactory.getBean()
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean()
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton()
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$0(AbstractBeanFactory.java:312)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean()
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate()
org.springframework.beans.BeanUtils.instantiateClass()
这个方法就是实例化beanFactory中的BeanDefinition,该方法解决了bean循环引入问题,具体分析放到下次更新。
4.12、方法this.finishRefresh()暂不介绍。
5、总结spring初始化重要的8个方法:
this.prepareRefresh();
this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initApplicationEventMulticaster();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
spring初始化过程到此结束。如果错漏地方,望指出!!!
网友评论