spring初始化源码浅析之代码浅析
目录
1、refresh()简介
2、关键代码跟踪
2.1、obtainFreshBeanFactory()代码分析
2.2、invokeBeanFactoryPostProcessors(beanFactory)代码分析
2.3、registerBeanPostProcessors(beanFactory)代码分析
2.4、registerListeners()代码分析
2.5、finishBeanFactoryInitialization(beanFactory)代码分析
2.4、finishRefresh()代码分析
在《spring初始化源码浅析之关键类和扩展接口》中主要是关键类和扩展接口的介绍,本文主要是debug代码来看spring是如何初始化以及在分别在何时输出上文 demo中各扩展点的日志。
本文分为两部分:《spring初始化源码浅析之关键类和扩展接口》、《spring初始化源码浅析之代码浅析》
1、refresh()简介
通过ClassPathXmlApplicationContext构造方法进入 refresh方法
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//容器刷新前做一些准备工作prepareRefresh();// 创建DefaultListableBeanFactory对象,解析出所有BeanDefinition信息,//注册缓存在DefaultListableBeanFactory的beanDefinitionMap属性中,供后面创建bean对象时使用ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 为beanFactory提供一些标准配置,如:类加载器、环境变量等prepareBeanFactory(beanFactory);try {// 为beanFactory提供一些个性配置,通过在子上下文中复写该方法来实现postProcessBeanFactory(beanFactory);//创建实现BeanFactoryPostProcessor的实现类,并执行接口的方法。//该方法执行完后会输出实例中的1-7步的日志invokeBeanFactoryPostProcessors(beanFactory);//创建BeanPostProcessor的实现类,并注册到BeanFactoryPostProcessor的beanPostProcessors列表中,//在后面创建普通非lazy对象时会遍历该列表回调前置和后置方法registerBeanPostProcessors(beanFactory);//跟国际化消息相关,没去研究过initMessageSource();//初始化该上下文的事件广播initApplicationEventMulticaster();//模板方法,在不同的容器刷新的时候可以自定义逻辑onRefresh();//创建ApplicationListener的实现类,并注册到该上下文中registerListeners();//完成所有剩余的非lazy的bean的创建finishBeanFactoryInitialization(beanFactory);//上下文的创建完成的一些设置和缓存清理,并发布创建完成事件finishRefresh();}catch (BeansException ex) {……}finally {//Reset common introspection caches in Spring's core, since we//might not ever need metadata for singleton beans anymore...resetCommonCaches();}
}
2、关键代码跟踪
先看《spring初始化源码浅析之关键类和扩展接口》文中代码执行结果:
2.1、obtainFreshBeanFactory()代码分析
首先找到beanFactory的入口方法,如下
继续debug进入refreshBeanFactory方法,如下
从下图中可以看到,XmlBeanDefinitionReader为加载BeanDefinition的关键类,而将beanFactoy作为构造参数主要是为了将创建好的BeanDefinition对象注册到beanFactory中,后面会贴出相应的代码,如下
继续断点进入XmlBeanDefinitionReader的loadBeanDefinitions方法,可见入参为main方法中的指定配置文件的名称,如下
断点继续走,跳过将applicationContext.xml文件解析成Document的过程,进入registerBeanDefinitions(Document doc, Resource resource)方法,入参为applicationContext.xml对应的Document对象,该方法构造一个BeanDefinitionDocumentReader对象来具体的负责从doc对象创建BeanDefinition对象,并注册到beanFactory中,如下
注意 BeanDefinitionDocumentReader的registerBeanDefinitions方法一个入参为XmlReaderContext对象,该对象的reader即为前面创建XmlBeanDefinitionReader对象。
继续断点进入以下方法:
最后进入DefaultListableBeanFactory的registerBeanDefinition方法,最后将创建好的BeanDefinition对象缓存到DefaultListableBeanFactory的一个ConcurrentHashMap中
最终将配置文件中所有的bean配置转成BeanDefinition对象缓存起来,供后面创建具体的bean对象使用。
2.2、invokeBeanFactoryPostProcessors(beanFactory)代码分析
进入方法发现逻辑都交给PostProcessorRegistrationDelegate类来处理:
断点一直走到下面方法,先尝试从单利的缓存中去找,找不到再通过单例工厂类创建对象:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {………………singletonObject = singletonFactory.getObject();newSingleton = true;…………if (newSingleton) {//添加到单例缓存中addSingleton(beanName, singletonObject);}}return singletonObject;}
} //由于缓存单例对象的 hashmap没有hellword对象,进入singletonFactory.getObject()方法 ,
//继续断点到 AbstractAutowireCapableBeanFactory的doCreateBean放法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {//创建bean对象的包装器,beanName=hellowordService,//该方法执行完成后输出第一步日志:1->HelloWorldService constructorinstanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();//创建bean对象…………try {//从RootBeanDefinition 获取属性信息并填充到instanceWrapper对象populateBean(beanName, mbd, instanceWrapper);//进入初始化bean对象的操作exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}
}…………//将创建好的bean对象注册到缓存起来registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
…………
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 开始调用各种ware接口的方法,会输出2、3、4步的日志invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//执行BeanPostProcessor的前置方法postProcessBeforeInitialization,由于//ApplicationContextAwareProcessor实现该接口,该类中会执行很多*Aware的类,而hellwordService//实现ApplicationContextAware类,所在会输出:4->ApplicationContextAware.setApplicationContext:wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//init bean对象invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {//执行BeanPostProcessor的后置方法postProcessAfterInitialization,wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {//日志输出 2->BeanNameAware.setBeanName:helloWorldService((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {//日志输出 3->BeanFactoryAware.setBeanFactory:((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}…………protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {//日志输出:5->InitializingBean.afterPropertiesSet((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {//执行自定义init method方法,输出日志 :6->init methodinvokeCustomInitMethod(beanName, bean, mbd);}}}
}
最后回到getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {……//添加到单例缓存中addSingleton(beanName, singletonObject);
}
hellwordService对象创建完毕后,便执行 下一步的invokeBeanFactoryPostProcessors方法,输出第7步日志:
7->BeanFactoryPostProcessor.postProcessBeanFactory 将peopleService的content属性修改为i am ok
到此为止,invokeBeanFactoryPostProcessors(beanFactory);执行完毕
2.3、registerBeanPostProcessors(beanFactory)代码分析
可以看到代码和invokeBeanFactoryPostProcessors(beanFactory)的代码模式几乎一样,在本方法中会创建所有实现BeanPostProcessor接口类并注册到beanFactory中供后面对象创建时回调,代码不再做分析
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
2.4、registerListeners();代码分析
protected void registerListeners() {// Register statically specified listeners first.for (ApplicationListener<?> listener : getApplicationListeners()) {//hellowordService便在此处注册getApplicationEventMulticaster().addApplicationListener(listener);}
…………
}
2.5、finishBeanFactoryInitialization(beanFactory)代码分析
断点直接进入一下代码:
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//所有非lazy对象便在此处创建,如实例中的peopleServcie,对象创建过程前面已分析
//peopleServcie的创建过程回掉beanpostProcessors的前置和后置方法,输出日志:
//8->BeanPostProcessor.postProcessBeforeInitialization->peopleService
//9->BeanPostProcessor.postProcessAfterInitialization->peopleService
getBean(beanName);
}
}
}
…………
}
2.4、finishRefresh()代码分析
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).clearResourceCaches();// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.//发布ContextRefreshedEvent事件,输入日志//10->ApplicationListener.onApplicationEvent:publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);
}
到此代码分析完毕,以上只是简要的分析了初始化过程中关键代码,还有很多细节大家可自己断点跟踪。
spring初始化源码浅析之代码浅析相关推荐
- Spring 事务初始化源码分析
前言 在上篇文章 Spring 事务使用详解 中详细介绍了 Spring 事务的使用过程,今天就来看下 Spring 事务是如何来实现,比如 Spring 事务在初始化的时候做了什么,Spring 事 ...
- 从Spring源码探究AOP代码织入的过程
随着不断地使用Spring,以及后续的Boot.cloud,不断的体会到这个拯救Java的生态体系的强大,也使我对于这个框架有了极大的好奇心,以至于产生了我为什么不能写一个这样的框架的思考. 通过自学 ...
- Spring IoC容器初始化源码(1)—容器初始化入口以及setConfigLocations设置容器配置信息【一万字】
基于最新Spring 5.x,对于基于XML的Spring IoC容器初始化过程中的setConfigLocations设置容器配置信息方法的源码进行了详细分析,最后给出了比较详细的方法调用时序图 ...
- 【源码阅读计划】浅析 Java 线程池工作原理及核心源码
[源码阅读计划]浅析 Java 线程池工作原理及核心源码 为什么要用线程池? 线程池的设计 线程池如何维护自身状态? 线程池如何管理任务? execute函数执行过程(分配) getTask 函数(获 ...
- Spring Cloud源码分析(二)Ribbon(续)
因文章长度限制,故分为两篇.上一篇:<Spring Cloud源码分析(二)Ribbon> 负载均衡策略 通过上一篇对Ribbon的源码解读,我们已经对Ribbon实现的负载均衡器以及其中 ...
- Quartz的Scheduler初始化源码分析
2019独角兽企业重金招聘Python工程师标准>>> Quartz的使用:http://donald-draper.iteye.com/blog/2321886 Quartz的S ...
- Spring AOP 源码分析 - 拦截器链的执行过程
1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...
- Spring AOP 源码分析 - 创建代理对象
1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...
- Spring AOP 源码分析 - 筛选合适的通知器
1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析.本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出 ...
最新文章
- Solr4.7从数据库导数据
- python collections(容器)模块
- Your Bitbucket account has been locked. To unlock it and log in again you must solve a CAPTCHA.
- 关于异常信息未找到成员
- poj 楼天成的男人八题系列 A New Stone Game 博弈问题
- Java中==和equals()的区别
- 过年倒计时 java swing 附源码
- Linux操作系统——桌面和终端基本操作【快捷键、一般模式、编辑模式、 命令模式】
- Equations of Mathematical Magic题解
- ubuntu下点云库pcl错误问题集
- 项目经理如何做好项目管理PMP - 持续更新
- SpringMVC 用对象接收 ajax提交form表单
- Vs2005中操作WORD
- DaVinci:跟踪器 - 窗口
- docker学习笔记(k8s云原生学习前瞻)
- linux热点连上不通,一个WiFi模块开出多个热点(不可连接)
- C#实现多语言切换详细教程(附源码)
- 360N5全网通QPST备份NV和恢复教程
- Python中字典的基本操作
- 简单实用的jQuery分页插件twbs-pagination