源码解读全文
IOC
- IOC,Inversion of Control,控制反转
- 将对象创建和调用过程交给
Spring
进行管理singletonObjects
IOC容器的单例池
- DI,Dependency Injection,依赖注入
- 底层技术
- xml解析
- 工厂模式
- 反射
- 初始化三部曲
- 定位,定位配置文件和扫描相关注解
- 加载,将配置信息载入到内存
- 注册,根据载入的信息,将对象初始化到
IOC
中
- IOC容器,本质上是对象工厂,有两种实现方式
BeanFactory
,Spring
内部的使用接口,基本实现;加载配置文件的时候,不会创建对象,获取或使用
时才会进行创建ApplicationContext
,BeanFactory
的子接口,提供了更多功能,面向开发人员;加载配置文件中,就会被创建
对象与对象之间的关系
- 通过
xml/properties/yml/
文件进行表示 - 存在
classpath/network/filesystem/servletContext
- 通过
BeanDefinition
统一配置文件的标准 - 通过
策略模式
进行对不同的配置文件进行解析,最终输出成BeanDefinition
重要的接口和类
Resource
- 资源类,包含一些文件读取的方式,通过
NIO
的方式进行
- web资源
- 远程服务器
- 本地磁盘
ResourceLoader
- 资源加载器,进行加载资源,体现
策略模式
- 有多种实现策略
AbstractApplicationContext
,为容器类,也就是环境类,包含着ResourcePatternResolver
接口,并在初始化时,就为其赋值
BeanFactory
- IOC容器最顶层接口,定义容器,为
Spring
整体的结构,返回Bean
对象 - 设计模式
- 抽象工厂
- 模板方法
- 组合模式,
GenericApplicationContext
组合了DefaultListableBeanFactory
,可以获取所有的BeanFactory
HierarchicalBeanFactory
,定义工厂的父子关系ListableBeanFactory
,可列举的BeanFactory
,实现是DefaultListableBeanFactory
AutowireCapableBeanFactory
,自动装配工厂
DefaultListableBeanFactory
BeanDefinition
档案馆,同时是BeanFactory
,也是BeanDefinitionRegistry
,包锁了IOC所有的核心信息,且具有自动装配能力,实现了AutowireCapableBeanFactory
- 只保存
BeanDefinition
,Bean
的定义信息,相当于图纸 List<String> beanDefinitionNames
保存了所有beanDefinition
名字Map<Class<?>, String[]> singletonBeanNamesByType
,类型为key
,保存的beanName
池Map<String, BeanDefinition> beanDefinitionMap
保存所有beanDefinition
ApplicationContext
- 事件派发器、国际化解析、
bean
工厂(自动装配被组合进)、资源解析器
Aware
- 接口簇,需要使用
spring
中的组件,实现目标Aware
接口
DefaultSingletonBeanRegistry
Spring
默认的单例Bean
注册中心- 其实现
DefaultSingletonBeanRegistry
,包含实际上的单例池singletonObjects
享元模式,将单例
Bean
保存在map
中,相当于cache
BeanPostProcessor
Bean
功能增强,在于改变,围绕着Bean
的创建和初始化过程- 功能增强逻辑
- 注入了什么组件
- 在什么位置,用什么后置增强器,增强了什么
BeanFactoryPostProcessor
- 后置增强工厂
- 唯一的方法
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
InitializingBean
Bean
初始化后,属性注入完之后,进行额外处理
线程池初始化之后,进行属性的显示
BeanDefinition注册流程
- 断点在
DefaultListableBeanFactory
的registerBeanDefinition
- 获取所有
Bean
的定义信息,保存在BeanFactory
中 AppConfig.class
配置类,是在BeanFactoryRegistryPostProcessor
后置处理器ConfigurationClassPostProcessor
中进行处理
XML流程
- 在构建工厂时,进行
BeanDefinition
注册 - 整体流程
- 获取
xml
资源路径- 将
resource
包装为EncodedResource
,再转换为Document
- 由
BeanDefinitionParserDelegate
进行解释DefaultListableBeanFactory
加入到beanDefinitionMap
,完成注册
new ClassPathXmlApplicationContext("classpath:beans.xml")
refresh();
刷新容器ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
第一次创建beanFactory
,告诉子类
刷新内部工厂- 创建
DefaultListableBeanFactory
,赋值id,并loadBeanDefinitions(beanFactory);
- 准备读取器,将
beanFactory
分装成XmlBeanDefinitionReader
加载beanDenifition
,读取器中组合了IOC
容器和资源读取器
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
- 获取配置文件地址,并真正开始
递归
读取reader.loadBeanDefinitions(configLocations);
,并记录个数;根据解析器策略不同,进行单个/多个
解析资源 XmlBeanDefinitionReader
中进行registerBeanDefinitions(doc, resource)
,dom
解析,xml
变成document
文档,reader
实际上是负责解析doc
的,交由BeanDefinitionDocumentReader
进行真正解析
Document doc = doLoadDocument(inputSource, resource);
- 由
DefaultBeanDefinitionDocumentReader
调用parseBeanDefinitions(root, this.delegate);
,解析doc
,并由BeanDefinitionParserDelegate
进行逐个节点解析
BeanDefinitionParserDelegate
代理对象,是一个标签库和解析器
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
解析完标签后,封装成BeanDefinitionHolder
,使用工具类,进行注册,并会处理别名- 检查是否存在,不存在
this.beanDefinitionMap.put(beanName, beanDefinition);
放入 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
注册完成后,发出一个通知事件
配置类流程
- 注解配置,在工厂创建完成后,
BeanDefinitionRegistryPostProcessor
中的ConfigurationClassPostProcessor
进行创建并注册 register(componentClasses);
注册配置类ConfigurationClassPostProcessor
进行扫描处理,注册其他BeanDefinition
EncodedResource
- 运用了适配器模式,对接
Rescource
和InputStreamSource
BeanDefinitionParserDelegate
- 运用了解释器模式,包含了一个标签库,和解析方法,根据不同标签,进行不同的处理
创建BeanDefinition
- 断点在
AbstractBeanDefinition
空构造方法 - 获得
doc
文档后,解析出每一个节点,为其生成BeanDefinitionHolder
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
parseBeanDefinitionElement
进行标签解析- 最终调用
BeanDefinitionReaderUtils.createBeanDefinition(parentName, className, this.readerContext.getBeanClassLoader());
,封装成GenericBeanDefinition
- 解析
bean
标签内的其他信息
Bean创建流程
Aware
在完成bean
实例化后进行,帮助装配底层组件
- 所有单实例对象,都要从容器中先获取,没有再创建
Aware
功能由BeanPostProcessor
完成
流程
- 创建
BeanFactory
- 完成
BeanFactory
初始化,finishBeanFactoryInitialization(beanFactory);
AbstractApplicationContext
的refresh
方法中
- 初始化非懒加载的单实例
Bean
,beanFactory.preInstantiateSingletons();
!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
非抽象,是单例bean
,非懒加载- 处理
factoryBean
,但是都会调用getBean
Object sharedInstance = getSingleton(beanName);
尝试从缓存中获取
- 三级缓存的应用 循环依赖梳理
- 尝试获取父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
,从父工厂中尝试获取 - 标记该
Bean
的创建状态,this.alreadyCreated.add(beanName);
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
- 先处理
dependOn
,依赖的组件,先创建这些依赖的组件 getSingleton(beanName, mbd, args);
创建实例,是由ObjectFactory(lambda表达式)
进行调用,提供Bean
实例
该
getSingleton
方法中,会进行addSingleton(beanName, singletonObject);
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
//..
});
- 检查单例池,没有则锁住单例池
double check
beforeSingletonCreation(beanName);
,加入singletonsCurrentlyInCreation
singletonObject = singletonFactory.getObject();
真正开始创建,实际上调用createBean(beanName, mbd, args);
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
后置处理器的干预,可以让用户自定义Bean
的创建,直接返回
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
- 如果返回了,那么直接调用
BeanPostProcessor.postProcessAfterInitialization
,进行后置处理
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
创建Bean
实例。instanceWrapper = createBeanInstance(beanName, mbd, args);
,创建完成后,包装成BeanWrapper(包括bn, bd)
,准备进行其他配置
wrapper
功能增强与包装;holder
只包装Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
,通过SmartInstantiationAwareBeanPostProcessor
指定构造器ctors = mbd.getPreferredConstructors();
使用自定义指定的构造器instantiateBean(beanName, mbd);
,一般使用午参构造器,
- 根据不同的创建策略进行实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
SimpleInstantiationStrategy
利用反射,通过构造器创建CglibSubclassingInstantiationStrategy
,利用cglib
创建子类
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
,修改bd
信息
MergedBeanDefinitionPostProcessor
- 提前缓存刚刚创建好的
Bean
,还未进行赋值和其他初始化,解决循环依赖 populateBean(beanName, mbd, instanceWrapper);
注入环节
- 通过后置处理器执行
- 允许提早中断
exposedObject = initializeBean(beanName, exposedObject, mbd);
,对Bean
进行初始化
- 处理基础的
Aware
接口invokeAwareMethods(beanName, bean);
- 初始化前,通过后置处理器处理,包括
ApplicationContextAwareProcessor
进行,配置Spring
中的属性,invokeAwareInterfaces(bean);
,如果实现了Aware
接口就会进行处理- 初始化,实现
InitializingBean
接口- 初始化后,通过后置处理器处理
属性赋值
- 发生在
populateBean
中
xml方式
- 属性值获取
Bean
类型,从BeanFactory
获取Bean
- 普通属性,通过解析
value
属性获得,并保存在BD
中
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
从BeanDefinition
拿到所有的属性键值对- 没有
@Autowired
注解,直接在applyPropertyValues(beanName, mbd, bw, pvs);
进行属性赋值 - 遍历赋值
writeMethod.invoke(getWrappedInstance(), value);
通过反射获取set
方法进行赋值
writeMethod
为setter
Autowired
- 基于注解,处理
Autowired/Value/Inject
注解 populateBean(beanName, mbd, instanceWrapper);
赋值时执行postProcessAfterInstantiation
- 通过遍历
getBeanPostProcessorCache()
后置处理器缓存器缓存,利用AutowiredAnnotationBeanPostProcessor
进行处理 PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
进行属性赋值,位置与xml
不同InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
通过反射获取所有方法和属性,获取注解了Autowired
的element.inject(target, beanName, pvs);
遍历InjectedElement
,通过反射进行setter
@Autowired
在属性上,直接赋值,Filed
@Autowried
在方法上,调用其方法,并加入pvs
中,后续调用applyPropertyValues
进行属性赋值,Method
- 获取当前属性的
val
,调用result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
,通过String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
获取所有匹配上的BeanName
候选集合,是待注入类的实现或子类addCandidateEntry(result, candidate, descriptor, requiredType);
将类型加入候选集合result
- 如果查找到多个,进行名称匹配,如果对不上,则抛出异常
- 找到待注入的
BeanType
后,instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
通过getBean
生成Bean
applyPropertyValues(beanName, mbd, bw, pvs);
对@Autowired
添加到方法上的属性,进行真正赋值bw.setPropertyValues(mpvs);
,BeanWrapper
进行赋值