spring源码分析(一)

简介

Spring 是一个轻量级的企业级应用开发框架,于 2004 年发布了 1.0 版本。经过十几年的迭代,现在的 Spring 框架已经非常成熟了。Spring 包含了众多模块,包括但不限于 Core、Bean、Context、AOP 和 Web 等。在今天,我们完全可以使用 Spring 所提供的一站式解决方案开发出我们所需要的应用。作为 Java 程序员,我们会经常和 Spring 框架打交道,所以还是很有必要弄懂 Spring 的原理。

本文的源码分析文章是基于Spring 4.3.17.RELEASE版本编写的,而非最新的版本。好了,关于简介先说到这里,还是先来看一下思维导图吧!

总图预览

在这里插入图片描述

接下来简单说明一下,这个思维导图要怎么看。

IOC部分

创建bean部分

获取单例bean

开始是先简单分析、了解获取一个单例bean需要经历那些步骤。其中最重要的一步是创建并缓存bean,对于这个方法单独的提取出来作为一小节来分析。另外还会简单介绍一些方法执行时经常遇到的变量代表的意思。

创建单例bean

对于createBean方法,会先重缓存中获取对象,如果没有得到的话,会创建一个bean。也就引出了createBean方法的执行流程,在分析执行流程时会将涉及到的知识点简单介绍一下背景以及要怎么解决。如:lookup-method。

创建原始bean

在第二小节中会有一个创建原始bean的方法,这个方法涉及到的步骤挺多的,并且也是创建单例bean中比较重要的方法,所以单独拿出来分析。这个小节做的事情就是决定要使用哪种方式来创建bean,是用“工厂模式”?还是“构造器”方式?决定好创建方式后,还需要判断使用哪种代理模式来创建代理对象。这些个都在思维导图中有,并且简单的介绍了代理相关的知识。

解决循环依赖

这部分也对应第二小节中的一部分,解决方法也是挺简单的,就是提前暴露“早期引用”,对应到源码中也就是把需要提前暴露的对象放到一个集合中,这里也就没有对这个方法进行过多的分析。

填充属性

也是对应第二小节中的一部分,具体对应那一部分,图中有虚线的指向。填充属性时会有多个后置处理器的回调方法执行,不只是在填充属性时有后置处理器,在 创建原始bean 小节也是有后置处理器的执行。后置处理器 是spring中重要的一个组件,所以必须要了解它。

进行初始化操作

这是创建单例bean中的最后一个部分,这个部分也是有后置处理器的执行的。

IOC容器创建过程

这个部分直接贴我分析的过程,过程有点多,大家可以一小节一小节的来分析,最好还要走一遍DEGUB。分析的最后还有一个spring容器创建的简单总结。

方法的入口在创建ApplicationContext容器中。

refresh(); 方法分析
1、prepareRefresh(); 准备刷新工作
    1、this.scanner.clearCache();  清空缓存
        scanner 是 ClassPathBeanDefinitionScanner 类型
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
        最终会清空metadataReaderFactory中的map集合
    2、super.prepareRefresh();  准备刷新
        1、initPropertySources(); 初始化属性,该方法默认为空,可以被子类继承进行调用
        2、getEnvironment().validateRequiredProperties();
            StandardEnvironment进行校验属性
        3、this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
            创建一个早期的application的事件

2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 获取刷新好的的beanfactory
    1、refreshBeanFactory();  刷新beanFactory
        this.beanFactory.setSerializationId(getId());
        beanFactory是DefaultListableBeanFactory 类型的
        设置序列id号
    2、ConfigurableListableBeanFactory beanFactory = getBeanFactory();  获取beanFactory

3、prepareBeanFactory(beanFactory);  将上一步刷新号的beanFactory再次进行加工改造。也就是一些其他的赋值操作
	1、setBeanClassLoader、setBeanExpressionResolver、addPropertyEditorRegistrar
	2、添加一些可以用于方法回调的BeanPostProcessor
	3、注册一些简单的beanFactory
	4、注册Application监听器检查器
	5、添加一个LoadTimeWeaverAwareProcessor
	6、注册默认环境beans

4、postProcessBeanFactory(beanFactory);  给子类一个机会修改beanFactory
	该方法在beanFactory创建之前执行。 默认什么都不做,子类可以继承该方法

=========================================================================================================
============================================BeanFactory预准备============================================
=========================================================================================================

5、invokeBeanFactoryPostProcessors(beanFactory);  调用BeanFactory的后置处理器
	BeanFactoryPostProcessor 、 BeanDefinitionRegistryPostProcessors (一个自己的抽象方法,一个继承自BeanFactoryPostProcessor的抽象方法)、
	1、invokeBeanFactoryPostProcessors 方法调用所有的后置处理器
		1、 先来调用 BeanDefinitionRegistryPostProcessors 的后置处理器  
			1、获取所有的BeanDefinitionRegistryPostProcessor类型的postProcessors
			2、先从中区分出PriorityOrdered类型的,然后调用invokeBeanDefinitionRegistryPostProcessors 方法回调调用 后置通知
			3、再从中区分出Ordered类型的,然后调用invokeBeanDefinitionRegistryPostProcessors 方法回调调用 后置通知
			4、最后区分出其他类型的,然后调用invokeBeanDefinitionRegistryPostProcessors 方法回调调用 后置通知
			5、因为 BeanDefinitionRegistryPostProcessors 是 BeanFactoryPostProcessor 的子类,上面调用只是 BeanDefinitionRegistryPostProcessors 的后置通知方法,所以还需要再次调用 BeanFactoryPostProcessor 的后置通知方法
			
		2、 在来调用 BeanFactoryPostProcessor 的后置处理器 
			1、获取所有的 BeanFactoryPostProcessor 类型的postProcessors
			2、先从中区分出PriorityOrdered类型的,然后调用 invokeBeanFactoryPostProcessors  方法回调调用 BeanFactoryPostProcessor 后置通知
			3、再从中区分出Ordered类型的,然后调用 invokeBeanFactoryPostProcessors 方法回调调用 BeanFactoryPostProcessor 后置通知
			4、最后区分出其他类型的,然后调用 invokeBeanFactoryPostProcessors 方法回调调用 BeanFactoryPostProcessor 后置通知
			
	
6、registerBeanPostProcessors(beanFactory);  注册Bean的后置处理器,用于拦截Bean的创建
	不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
	BeanPostProcessor 、
	DestructionAwareBeanPostProcessor (bean销毁的后置处理器)、
	InstantiationAwareBeanPostProcessor (bean实例化的后置处理器)、
	SmartInstantiationAwareBeanPostProcessor (常被spring容器内部使用)、
	MergedBeanDefinitionPostProcessor 【internalPostProcessors】 (合并Bean的定义信息后置处理器) 、
	
	1、 先获取 BeanPostProcessor 类型的name
	2、	注册一个 BeanPostProcessorChecker 后置处理器
	3、 先区分出 PriorityOrdered 、 Ordered 、 其他类型、MergedBeanDefinitionPostProcessor 
	4、 然后依次调用PriorityOrdered 、 Ordered 、 其他类型、MergedBeanDefinitionPostProcessor 的后置方法
	5、 再次添加 一个 ApplicationListenerDetector 后置处理器 
	
7、initMessageSource(); 初始化国际化相关信息
	1、 如果beanFactory中 有 messageSource ,就设置 messageSource 的父子关系
	2、 没有的话,创建一个 DelegatingMessageSource() ,设置父子关系,然后把新创建的DelegatingMessageSource 注册到beanFactory中
	
8、initApplicationEventMulticaster(); 初始化spring事件派发器
	1、 如果beanFactory中有 applicationEventMulticaster bean,将该bean赋值给 this.applicationEventMulticaster 
	2、 没有的话,会创建一个 SimpleApplicationEventMulticaster 事件派发器bean,然后将该bean注册到beanFactory中
	
9、onRefresh();  用于刷新其他bean,该方法默认什么都不做,可以被子类重写

10、registerListeners(); 检查并注册listeners
	1、 首先注册静态的特殊的listener。 也就是事件派发器的监听器
	2、 从beanFactory中拿到 ApplicationListener 类型的bean,然后依次添加到事件派发器的ApplicationListenerBean中
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	3、 发布需要使用的早期事件
		getApplicationEventMulticaster().multicastEvent(earlyEvent);
		
11、finishBeanFactoryInitialization(beanFactory);  完成剩下的bean的初始化
	1、 先初始化conversion service 相关的bean
	2、 beanFactory中如果没有的话,注册一个默认的值解析器 beanFactory.addEmbeddedValueResolver()
	3、 初始化 LoadTimeWeaverAware 相关的bean
	4、 停止使用temporary ClassLoader 来匹配
	5、 允许缓存所有的bean定义的原信息,缓存的这些信息是不能被修改的
	6、 【初始化剩下的bean】 beanFactory.preInstantiateSingletons();
		1、 获取所有的bean定义信息名字,遍历之
			1、 对于单实例的bean,如果是工厂bean,获取该工厂bean,然后使用getBean 创建实例
			2、 如果不是工厂bean,直接调用getBean 创建实例
				getBean方法 调用 doGetBean 方法 
				1、 先对beanName进行转换。transformedBeanName(name); 可能是工厂bean(以&符号开头)
				2、 从 Map<String, Object> singletonObjects 中获取缓存的单实例的bean。 getSingleton(beanName);
				3、 如果缓存中的单实例bean,不为空,
					1、 调用 getObjectForBeanInstance 方法进行一些简单的操作
						1、 如果不是工厂Bean,直接返回
						2、 不是工厂Bean,先从工厂bean的缓存中获取获取bean。getCachedObjectForFactoryBean(beanName);
						3、 获取bean为空,
							1、 将参数中的bean实例转为FactoryBean,
							2、 调用 getObjectFromFactoryBean(factory, beanName, !synthetic); 获取bean 
								如果 factory是 单实例的
								1、 从工厂bean中拿到 实例
									Object object = this.factoryBeanObjectCache.get(beanName);
								2、 object 为空,调用 doGetObjectFromFactoryBean(factory, beanName); 获取bean
									1、 调用 factory.getObject(); 获取bean并返回
								3、 再次调用 1 的 方法 
									Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
								4、 如果 alreadyThere 不为空,就使用这个
								5、 如果为空,
									1、 beforePrototypeCreation(beanName);  做一些简单的校验
									2、 postProcessObjectFromFactoryBean(object, beanName); 获取bean
										1、 直接返回object
									3、 afterPrototypeCreation(beanName);	做一些简单的校验	
								6、 返回 object
								如果 factory 不是单实例
								1、 调用 doGetObjectFromFactoryBean 方法返回bean
								2、 调用 postProcessObjectFromFactoryBean(object, beanName); 获取bean
								3、 返回 得到的bean
						3、 返回bean				
				4、 缓存的单实例为空,  
					1、 先检查beanFactory中是否有bean的定义信息
					2、 标记该bean为正在创建状态
					3、 获取bean的根定义信息 
					4、 获取bean的依赖bean,循环注册、创建
					5、 如果是单实例的话,
						1、 调用 createBean 方法创建bean,
							1、 解析bean的class,确保bean已经被解析过
							2、 准备方法重载 mbdToUse.prepareMethodOverrides();
								检查 lookip-method 方法 是否存在。
								lookup-method : 一个单实例bean中的某个属性是多实例的
								解决方法:1、 实现ApplicationContextAware接口 2、 使用lookup-method
							3、 调用bean的后置处理器 resolveBeforeInstantiation(beanName, mbdToUse); 
								如果 后置处理器返回的bean不为空,就直接返回
								该方法用于给后置处理器一个返回代理对象的机会
								1、 调用 hasInstantiationAwareBeanPostProcessors() 方法 判断是否是对应的后置处理器
									InstantiationAwareBeanPostProcessor 后置处理器
								2、 如果是 InstantiationAwareBeanPostProcessors 类型的
									1、 调用 applyBeanPostProcessorsBeforeInstantiation 方法,调用后置处理器
									2、 上面结果不为空时,再调用applyBeanPostProcessorsAfterInitialization 后置处理器方法
									这里说明下,一般是在前置处理时会返回一个代理对象,也就是前置处理方法中包含 创建对象 的过程,
									这样才有后置处理。									
							4、 调用 doCreateBean(beanName, mbdToUse, args); 创建bean并放回					
						2、 然后调用 getObjectForBeanInstance 方法进行简单处理
							1、 调用 createBeanInstance 方法创建对象  使用反射创建对象
								1、 如果是按照工厂模式创建bean
								2、 如果是按照(有参)构造方法创建bean
								3、 如果是按照(默认)构造方法创建bean
							2、 调用 applyMergedBeanDefinitionPostProcessors 方法,执行后置处理
								如果是 MergedBeanDefinitionPostProcessor 后代,调用 postProcessMergedBeanDefinition 后置处理器方法
							3、 确定是否要提前暴露 实例。用于解决 循环引用问题
							4、 调用 populateBean 填充bean属性
								1、 获取属性值
								2、 获取所有的beanPostProcessor,遍历之
									如果是 InstantiationAwareBeanPostProcessor 类型调用其后置处理器方法(对象创建后后置处理方法)
								3、 按照name、type类型来,执行相应的autowrite操作,确定赋值操作的方式
								4、 再次获取所有的beanPostProcessor,遍历之
									如果是 InstantiationAwareBeanPostProcessor 类型调用其后置处理器方法(属性赋值前后置处理方法)
								5、 调用 applyPropertyValues 方法 完成属性赋值 									
							5、 上步返回结果不为空,调用 initializeBean 方法,初始化bean
								1、 调用 invokeAwareMethods(beanName, bean); 方法,完成XXXAware的回调方法
								2、 调用 applyBeanPostProcessorsBeforeInitialization 方法,执行	初始化前的后置操作
								3、 执行初始化操作
								4、 调用 applyBeanPostProcessorsAfterInitialization 方法,执行 初始化后的后置操作
							6、 解决需要提前暴露bean锁依赖的bean
							7、 调用 registerDisposableBeanIfNecessary 方法,按照需求注册
								在bean对应的作用域中进行注册或缓存操作
					6、 如果是多实例的话,
						1、 beforePrototypeCreation(beanName); 
						2、 createBean 创建bean
						3、 afterPrototypeCreation(beanName); 
						4、 getObjectForBeanInstance() 调用该方法进行简单的处理
					7、 其他情况
						1、 获取bean的作用域
						2、 合法的话,按照 多实例 来创建bean
				5、 按照需求转换bean的类型
					1、 getTypeConverter().convertIfNecessary(bean, requiredType); 
				6、 返回bean
						
		2、 再次遍历所有的bean定义信息名字,如果是 SmartInitializingSingleton 类型,就会调用其后置处理器方法
					
		
12、finishRefresh(); 完成刷新
	1、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
			默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
			加入到容器;
			
			写一个LifecycleProcessor的实现类,可以在BeanFactory
				void onRefresh();
				void onClose();	
	2、	getLifecycleProcessor().onRefresh();
			拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
	3、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
	4、liveBeansView.registerApplicationContext(this);
==================================================================================================
===============================================总结===============================================
==================================================================================================
	1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;
		1)、xml注册bean;<bean>
		2)、注解注册Bean;@Service、@Component、@Bean、xxx
	2)、Spring容器会合适的时机创建这些Bean
		1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
		2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
	3)、后置处理器;BeanPostProcessor
		1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
			AutowiredAnnotationBeanPostProcessor:处理自动注入
			AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
			xxx....
			增强的功能注解:
			AsyncAnnotationBeanPostProcessor
			....
	4)、事件驱动模型;
		ApplicationListener;事件监听;
		ApplicationEventMulticaster;事件派发:





最后

本片的篇幅有点多了,如果再写的话各位可能就不想看了,所以AOP和MVC部分就在下片文章分析啦!见谅! → → → Spring源码分析(二)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值