目录
6. 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)
使用示例:
ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("springConf.xml");
UserService userService1 = (UserService) applicationContext1.getBean("userService");
userService1.query();
分析:
- 实例化ClassPathXmlApplicationContext示例, 使用接口ApplicationContext接收
- 调用getBean()获取bean
- 执行目标bean的方法
ClassPathXmlApplicationContext#ClassPathXmlApplicationContext实现:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
//设置资源位置
setConfigLocations(configLocations);
if (refresh) {
/**
* 调用父类的refresh()方法 <经典的模板方法模式>
*/
refresh();
}
}
分析:
- 设置父类上下文信息
- 设置资源位置
- 调用父类AbstractApplicationContext的refresh()方法初始化容器 (重点)
AbstractApplicationContext#refresh实现 <核心方法>:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备好刷新上下文(设置一些变量)
prepareRefresh();
/**
* obtainFreshBeanFactory()方法中根据实现类的不同调用不同的refreshBeanFactory()方法
* <----- 注解模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
* 调用的是GenericApplicationContext#refreshBeanFactory()方法
* {@link GenericApplicationContext#refreshBeanFactory()}
* 在该方法中只是对beanFactory的一些变量进行设置
* <----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
* 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
* 并对设置的资源位置进行扫描, 解析
* 注意:此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口 <-------------------重要
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//对beanFactory进行属性设置
prepareBeanFactory(beanFactory);
try {
//允许在子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
/**
* <----- 注解模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口) <--------------------重要
* 在该方法中执行了
* {@link org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法
* 对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作) <--------------- 重要
* 注意:
* 1. 一般情况下, 此时beanFactory中只注册了这一个BeanFactoryPostProcessor类-->ConfigurationClassPostProcessor
* 在{@link AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)}中注册的
* 2. 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类, 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作
* 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息
*
* <----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器
* 除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
*
*/
invokeBeanFactoryPostProcessors(beanFactory);
//注册拦截bean创建的bean后处理处理器。
registerBeanPostProcessors(beanFactory);
//为上下文初始化Message源,即不同的语言体,国际化处理
initMessageSource();
// 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
initApplicationEventMulticaster();
// 留给子类来初始化其他的Bean
onRefresh();
//在所有注册的bean中查找listener bean,注册到消息广播器中
registerListeners();
// 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
finishBeanFactoryInitialization(beanFactory);
//最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例以避免资源悬空。
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
resetCommonCaches();
}
}
}
分析:
- prepareRefresh(): 准备刷新上下文, 设置相关监听器, 以及状态开关的设置
- obtainFreshBeanFactory(): (1) 如果是使用AnnotationConfigApplicationContext来初始化环境: 调用的是GenericApplicationContext#refreshBeanFactory()方法,在该方法中只是对beanFactory的一些变量进行设置;
(2) 如果是使用ClassPathXmlApplicationContext来初始化环境: 调用的是AbstractRefreshableApplicationContext#refreshBeanFactory(), 由于还没有对beanFactory进行初始化, 所以在该方法中, 完成了对beanFactory的初始化操作, 并对设置的资源位置进行扫描, 解析; 注意: 此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口
prepareBeanFactory(beanFactory): 对beanFactory相关配置进行设置; 设置bean工厂的类加载器, 表达式语言处理器, 工厂后处理器, 以及需要忽略的自动装配的接口
postProcessBeanFactory(beanFactory): 留给子类实现, 允许在子类中对bean工厂进行后处理
invokeBeanFactoryPostProcessors(beanFactory): 激活bean工厂的后处理器 (1) 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口)在该方法中执行了ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作) (2) 如果是使用ClassPathXmlApplicationContext来初始化环境, 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器; 除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
注意: 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类(但是只有一个BeanFactoryPostProcessor类的实例-->ConfigurationClassPostProcessor), 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作; 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息registerBeanPostProcessors(beanFactory): 注册bean后处理处理器
initMessageSource(): 为上下文初始化Message源,即不同的语言体,国际化处理
initApplicationEventMulticaster(): 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
onRefresh(): 留给子类来初始化其他的Bean
registerListeners(): 在所有注册的bean中查找listener bean,注册到消息广播器中
finishBeanFactoryInitialization(beanFactory): 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
finishRefresh(): 最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
destroyBeans(): 销毁已创建的单例bean, 避免资源悬空
cancelRefresh(ex): 重置状态开关
注: Spring容器的初始化过程主要由上面的流程实现, 这篇博客将以Xml配置进行解析, 关于注解方式会在后面解析AnnotationConfigApplicationContext时进行解析;
1. 刷新, 获取Bean工厂
_2. AbstractApplicationContext#obtainFreshBeanFactory方法实现:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/**
* 此处根据实现类的不同调用不同的refreshBeanFactory()方法
*<----- 注解配置模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
* 调用的是GenericApplicationContext#refreshBeanFactory()方法
* {@link GenericApplicationContext#refreshBeanFactory()}
* 在该方法中只是对beanFactory的一些变量进行设置
*
*<----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
* 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
* 注意:两种方式都使用的是间接继承AbstractApplicationContext这个抽象类,并重写refreshBeanFactory()方法
*/
refreshBeanFactory();
/**
* 返回已经刷新完成的bean工厂
*/
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
...
return beanFactory;
}
分析:
- refreshBeanFactory(): 根据子类的不同实现, 执行不同的逻辑; 这里着重分析使用ClassPathXmlApplicationContext来初始化环境时, 调用AbstractRefreshableApplicationContext#refreshBeanFactory()方法; (间接继承AbstractApplicationContext这个抽象类,并重写refreshBeanFactory()方法)
- 返回刷新完成的bean工厂 (由AbstractRefreshableApplicationContext#getBeanFactory()方法实现)
1.1 Bean工厂的刷新以及相关配置
_1. AbstractRefreshableApplicationContext#refreshBeanFactory实现:
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果beanFactory已存在,则销毁重新创建
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建DefaultListBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//为了序列化指定id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
/**
* 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
* 设置@Autowired和@Qualifer注解解析器QualifierAnnotationAutowire CandidateResolver
*/
customizeBeanFactory(beanFactory);
/**
* 初始化DodumentReader,并进行XML文件读取及解析
*1. Spring: {@link AbstractXmlApplicationContext#loadBeanDefinitions}
*2. SpringMvc: {@link org.springframework.web.context.support.XmlWebApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)}
*/
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
...
}
分析:
- 如果beanFactory已存在, 则销毁重新创建
- 创建DefaultListBeanFactory (DefaultListBeanFactory中维护注册BeanDefinition的容器,以及注册BeanName集合信息等)
- 定制beanFactory,设置相关属性, 包括是否允许覆盖同名称的不同定义的对象以及循环依赖, 设置@Autowired和@Qualifer注解解析器QualifierAnnotationAutowire CandidateResolver
- 加载BeanDefinition; 初始化DodumentReader, 并进行XML文件读取及解析
1.2 BeanDefinition的预加载
_4. AbstractXmlApplicationContext#loadBeanDefinitions实现:
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//为指定bean创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//对beanDefinitionReader进行环境变量的设置
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//对BeanDefinition进行设置,可以覆盖
initBeanDefinitionReader(beanDefinitionReader);
/**
* 加载BeanDefinition
*/
loadBeanDefinitions(beanDefinitionReader);
}
分析:
- 创建解析器XmlBeanDefinitionReader, 以及相关配置设置
- 加载BeanDefinition
AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)
==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)
==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)
==> XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
==> XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)实现:
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//1.非空判断及日志记录
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource);
}
//2.通过set集合来记录当前正在加载的资源
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
//将encodedResource添加到currentResources集合中,如果添加失败,则抛出异常
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
//3.加载bean
try {
//通过encodedResource获取已经封装的Resource对象并再次从Resource中获取其中的inputStream
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//org.xml.sax.InputSource
InputSource inputSource = new InputSource(inputStream);
//如果encodedResource中设置的编码不为空,则设置inputSource的编码
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
/**
* 加载bean,核心部分
*/
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
//关闭输入流
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
//加载完毕,将encodedResource从集合中移除
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
分析:
- 通过currentResources集合来记录当前正在加载的资源, 并将需要加载的encodedResource添加到currentResources集合中,如果添加失败,则抛出异常
- 获取资源输入流并封装为InputSource; 加载bean,核心部分
_2. XmlBeanDefinitionReader#doLoadBeanDefinitions实现:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
/**
* 将配置文件解析为一个Document实例,以便下面对Bean定义进行解析
*/
Document doc = doLoadDocument(inputSource, resource);
/**
* 上一个方法中当把文件装换为Document后,接下来就是对bean的提取及注册
* 注册bean定义
*/
return registerBeanDefinitions(doc, resource);
}
//异常捕获
...
}
分析:
- 将配置文件解析为一个Document实例, 以便下面对Bean定义进行解析; 在解析之前会获取资源文件的验证方式(DTD或XSD)
- 对bean的提取及注册bean定义
XmlBeanDefinitionReader#registerBeanDefinitions实现:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//实例化BeanDefinitionDocumentReader接口
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//记录统计前BeanDefinition的加载个数
int countBefore = getRegistry().getBeanDefinitionCount();
/**
* 加载及注册bean
* {@link org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions(Document, XmlReaderContext)}
*/
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//记录本次加载的BeanDefinition个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
分析:
- 创建Bean定义信息解析器 (DefaultBeanDefinitionDocumentReader)
- 加载及注册bean
- 返回本次注册Bean定义的数量
DefaultBeanDefinitionDocumentReader#registerBeanDefinitions实现:
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
/**
* 获取节点的根节点,并将root作为参数继续BeanDefinition的注册
*/
doRegisterBeanDefinitions(root);
}
分析: 获取配置文件的根节点, 开始注册Bean定义信息
2. 注册BeanDefinition
DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions实现:
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
...
//解析前处理,留给子类实现(设计模式:模板方法模式)
preProcessXml(root);
/**
* 根据Root节点进行解析
*/
parseBeanDefinitions(root, this.delegate);
//解析后处理,留给子类实现(设计模式:模板方法模式)
postProcessXml(root);
this.delegate = parent;
}
DefaultBeanDefinitionDocumentReader#parseBeanDefinitions实现:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//如果beans是默认命名空间
if (delegate.isDefaultNamespace(root)) {
//获取beans的所有子节点,遍历,对其子节点根据是否使用默认命名空间,使用不同的解析方法
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
//判断是否是默认命名空间
if (delegate.isDefaultNamespace(ele)) {
/**
* 如果是默认命名空间(对bean的处理)
*/
parseDefaultElement(ele, delegate);
}
else {
/**
* 如果不是默认命名空间(对bean的处理)
*/
delegate.parseCustomElement(ele);
}
}
}
}
//如果beans不是默认命名空间
else {
delegate.parseCustomElement(root);
}
}
分析:
- 默认命名空间解析
- 自定义命名空间解析
2.1 默认命名空间解析
DefaultBeanDefinitionDocumentReader#parseDefaultElement实现:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
/**
* 对import标签进行处理
*/
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
/**
* 对alias标签进行处理
*/
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
/**
* 对bean标签进行处理
*/
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
/**
* 对beans标签进行处理
*/
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse 递归
doRegisterBeanDefinitions(ele);
}
}
分析:
- 对<import>标签进行处理
- 对<alias>标签进行处理
- 对<bean>标签进行处理(这里只分析<bean>标签的解析)
- 对<beans>标签进行处理
2.1.1 <bean>标签处理解析
_3. DefaultBeanDefinitionDocumentReader#processBeanDefinition实现:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
/**
* 1.解析ele,返回BeanDefinitionHolder类型实例bdHolder,经过这个方法后,bdHolder实例已经包含我们配置文件中配置的各种属性,例如:class,name,id,alias等
*/
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
/**
* 2.当返回的bdHolder不为空的情况下若存在默认标签的字标签下再有自定义属性,还需要再次对自定义标签进行解析
*/
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
/**
* 3.对bdHolder进行注册
*/
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
//4.发出相应事件,通知相关的监听器,这个bean已经被加载完了
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
分析:
- 解析ele, 返回BeanDefinitionHolder类型实例bdHolder, 经过这个方法后, bdHolder实例已经包含我们配置文件中配置的各种属性, 例如:class,name,id,alias等
- 当返回的bdHolder不为空的情况下若存在默认标签的字标签下再有自定义属性,还需要再次对自定义标签进行解析
- 对bdHolder进行注册
- 发出相应事件,通知相关的监听器,这个bean已经被加载完了
_3. BeanDefinitionReaderUtils#registerBeanDefinition实现:
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {
// 根据主名称注册bean定义信息
String beanName = definitionHolder.getBeanName();
/**
* GenericApplicationContext类实现了BeanDefinitionRegistry接口,
* 并且在 GenericApplicationContext类中维护了一个DefaultListableBeanFactory beanFactory (卧槽, 终于见到bean工厂了)
*
* 该步骤实际调用的是GenericApplicationContext类中的registerBeanDefinition()方法
*{@link org.springframework.context.support.GenericApplicationContext#registerBeanDefinition(String,BeanDefinition)}
*/
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果该bean有别名的话, 为bean名称注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
分析:
- 获取beanName, 注册Bean定义信息时以BeanName为键进行注册
- 注册BeanDefinition
- 注册别名(key=beanName, value=alias)
_2. GenericApplicationContext类定义信息:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
//bean工厂, 用来注册bean定义信息
//DefaultListableBeanFactory中维护了一个
private final DefaultListableBeanFactory beanFactory;
. . . . . .
}
2.1.2 BeanDefinition的注册
GenericApplicationContext#registerBeanDefinition ==> DefaultListableBeanFactory#registerBeanDefinition实现:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
. . .
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
/**
* 注册前的最后一次校验,这里的校验不同于之前的XML文件校验
* 主要是对于AbstracBeanDefinition属性中的methodOverrides校验,
* 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
. . .
}
//判断该beanName是否已经注册 ,根据不同的设置记性处理; (不愧是Spring, 在我模拟的SpringIOC中我管它那么多, 直接覆盖 ,简单粗暴)
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//如果对应的BeanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常
. . .
//注册beanDefinition(将beanDefinition放入map缓存中)
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//处理注册未被注册的beanName的情况
else {
/**
* 检查这个工厂的bean创建阶段是否已经开始,即 是否有任何bean被标记为同时创建。
* 如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合,获取beanName,获取BeanDefinition创建bean实例
* 一旦开始迭代, 则不允许在向该map集合中插入元素
*/
if (hasBeanCreationStarted()) {
//处于bean创建阶段
//因为beanDefinitionMap是全局变量,这里肯定会存在并发访问的情况
synchronized (this.beanDefinitionMap) {
//注册beanDefinitionv
this.beanDefinitionMap.put(beanName, beanDefinition);
//创建新的集合来更新存储已注册beanName的beanDefinitionNames集合
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
//更新manualSingletonNames(存储单例bean)集合
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
//仍处于注册阶段
else {
//将beanName和bean的定义信息加入beanDefinitionMap集合
this.beanDefinitionMap.put(beanName, beanDefinition);
//bean定义名称列表,按注册顺序排列
this.beanDefinitionNames.add(beanName);
//手动注册的单例程序的名称列表,按注册顺序排列
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
//如果该bean定义已经注册,并且为单例,则进行重置
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
分析:
- 注册前的最后一次校验,这里的校验不同于之前的XML文件校验, 主要是对于AbstracBeanDefinition属性中的methodOverrides校验, 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
- 判断该beanName是否已经注册; 如果beanName已经注册过: 根据不同的设置进行处理(是否允许覆盖, 如果不允许,则抛出异常; 允许的话, 则进行注册)
- 如果beanName没有被注册过; 则开始检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean被标记为同时创建。如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合, 获取beanName, 获取BeanDefinition创建bean实例; 一旦开始迭代, 则不允许在向该list集合中插入元素, 但是beanDefinitionMap集合可以, 因为beanDefinitionMap集合并没有被迭代, 而是通过beanName获取BeanDefinition信息;
- 如果该bean定义已经注册, 并且为单例, 则进行重置
2.2 自定义命名空间解析
BeanDefinitionParserDelegate#parseCustomElement实现:
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
/**spring.handler:
* http\://www.lic.com/schema/user=test.MyNameSpaceHandler
* 命名空间 NamespaceHandler
*/
/**
* 1.获取对应的命名空间
*/
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
/**
* 2.根据命名空间找到对应的NameSpaceHandler,用来解析XSD文件中的定义和组件定义
* {@link org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve(java.lang.String)}
*/
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
/**
* 3.调用自定义的NamespaceHandler进行解析
* {@link NamespaceHandlerSupport#parse(Element, ParserContext)}
*/
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
分析:
- 获取对应的命名空间
- 根据命名空间找到对应的NameSpaceHandler, 用来解析XSD文件中的定义和组件定义
- 调用自定义的NamespaceHandler进行解析
2.2.1 获取名称处理器
_2. DefaultNamespaceHandlerResolver#resolve
public NamespaceHandler resolve(String namespaceUri) {
/**
* 获取所有已经配置的handler映射
*/
Map<String, Object> handlerMappings = getHandlerMappings();
//根据命名空间找到对应的信息
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
else if (handlerOrClassName instanceof NamespaceHandler) {
//已经做过解析的情况,直接从缓存读取
return (NamespaceHandler) handlerOrClassName;
}
else {
//没有做过解析,则返回的是类路径
String className = (String) handlerOrClassName;
try {
//利用反射将类路径转换为类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
...
//初始化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
/**
* 调用自定义的NamespaceHandler的初始化方法
* SpringMvc: {@link org.springframework.web.servlet.config.MvcNamespaceHandler#init()}
*/
namespaceHandler.init();
//将该handler记录在缓存中,以便下次调用该handler可以直接获取,不用再次转换
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
...
}
}
分析:
- 获取所有已经配置的handler映射
- 根据命名空间找到对应的信息
- 已经做过解析的情况,直接从缓存读取; 没有做过解析,则返回的是类路径,利用反射将类路径转换为类
- 调用自定义的NamespaceHandler的初始化方法; 初始化NamespaceHandler
示例: SpringMvc的名称空间解析器初始化方法:
@Override
public void init() {
/**
* 将标签名称与对应解析器关联
*
* 第一次尝试获取MvcNamespaceHandler时会调用该初始化方法进行初始化
*/
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
}
_3. NamespaceHandlerSupport#parse实现:
public BeanDefinition parse(Element element, ParserContext parserContext) {
/**
* 寻找解析器并进行解析操作,在自定义handler中并没有重写父类中parse()方法,因此此处是调用父类AbstractBeanDefinitionParser中的parse()方法
*
* 在parse()方法中根据标签命名空间获取不同的解析进行解析
* 例如: 标签:<context:component-scan base-package="com.ioc.lic"/>的解析为ComponentScanBeanDefinitionParser
* 该解析器会去解析包路径信息, 注册包路径下的所有BeanDefinition
*/
BeanDefinitionParser parser = findParserForElement(element, parserContext);
/**
* 解析器1:
* {@link AbstractBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
* 解析器2:<context:component-scan base-package="com.ioc.lic"/>
* {@link org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
*/
return (parser != null ? parser.parse(element, parserContext) : null);
}
分析:
- 根据不同的定义标签获取对应的解析器进行解析
- 调用解析器中的parse()解析该标签 (这里以<context:component-scan base-package="com.ioc.lic"/>标签为例进行分析)
2.2.2 根据标签名称获取解析器
_1.NamespaceHandlerSupport#findParserForElement实现:
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//获取元素名称,也就是<myname:user>中的user,若在实例中,此时localName为user
String localName = parserContext.getDelegate().getLocalName(element);
//根据user找到对应的解析器,也就是在 registerBeanDefinitionParser("user", new UserBeanDefinitionParser()) 中注册的解析器
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
2.2.3 解析自定义标签
ComponentScanBeanDefinitionParser#parse实现:
public final BeanDefinition parse(Element element, ParserContext parserContext) {
/**
* 解析element
* {@link AbstractSingleBeanDefinitionParser#parseInternal(Element, ParserContext)}
*/
AbstractBeanDefinition definition = parseInternal(element, parserContext);
if (definition != null && !parserContext.isNested()) {
try {
...
//将AbstractBeanDefinition装换成BeanDefinitionHolder并注册
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
//注册
registerBeanDefinition(holder, parserContext.getRegistry());
if (shouldFireEvents()) {
//需要通知监听器进行处理
BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
postProcessComponentDefinition(componentDefinition);
parserContext.registerComponent(componentDefinition);
}
}
...
}
return definition;
}
分析:
- 获取到包路径信息
- 配置扫描器, 扫描包路径, 注册BeanDefinition
ClassPathBeanDefinitionScanner#doScan实现:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//存储扫描到的BeanDefinition信息
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
/**
* 循环遍历包路径信息,进行解析,注册
*/
for (String basePackage : basePackages) {
/**
* 扫描出该包路径下左右的候选Bean
*/
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
/**
* 对所有的候选bean进行解析
*/
for (BeanDefinition candidate : candidates) {
//获取Scope属性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//根据Bean信息生成BeanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//对于配置类型BeanDefinition类型和注解类型BeanDefinition类型进行区分设置
if (candidate instanceof AbstractBeanDefinition) {
/**
* 如果这个类是AbstractBeanDefinition的子类
* 则为他设置默认值,比如lazy,init destory
*/
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
/**
* 检查并且处理常用的注解
* 这里的处理主要是指把常用注解的值设置到AnnotatedBeanDefinition当中
* 当前前提是这个类必须是AnnotatedBeanDefinition类型的,说白了就是加了注解的类
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//判断注册器中是否已经存在该BeanName
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
/**
* 注册BeanDefinition
*/
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
3. Bean工厂配置的设置
_3. AbstractApplicationContext#prepareBeanFactory实现:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类加载器等等。
beanFactory.setBeanClassLoader(getClassLoader());
//设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持
//默认可以使用#{bean.xxx}的形式来调用相关属性值
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为beanfactory增加了一个默认的属性编辑器,这个主要是对bean的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 给beanFactory添加后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置了几个忽略自动装配的接口()
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.\
//设置了几个自动装配的特殊规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//增加对AspectJ的支持
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//添加默认系统环境bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
4. 激活Bean工厂后处理器
_5. AbstractApplicationContext#invokeBeanFactoryPostProcessors实现:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* getBeanFactoryPostProcessors()方法:
* 获取通过{@link AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor)}
* 方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
*
* 注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描
* 如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 检测LoadTimeWeaver并准备编织(如果在此期间发现)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
分析:
- getBeanFactoryPostProcessors()方法: 获取通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
- 激活Bean工厂后处理器; 通常情况下这里主要激活的是Spring内部的工厂后处理器
注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描; 如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors实现:
/**
* 1. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
*
* 2. 执行Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
*
* 3. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法
* 和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
*
* 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, ConfigurableListableBeanFactory)}
*
*
*/
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
//注意: 前提条件是改注册器是实现了BeanDefinitionRegistry接口的
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
/**
* 1. 将自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的类区分保存在不同的集合中
* 在区分过程中执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
*/
/**
* 注意: BeanDefinitionRegistryPostProcessor接口 继承了 BeanFactoryPostProcessor接口
* 之所以要将所有的后处理器区分开, 是因为实现BeanDefinitionRegistryPostProcessor接口的要执行两个方法
* {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
* 和{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}这两个方法
* 而实现BeanFactoryPostProcessor接口的只需要执行{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
* 这个方法即可
*/
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/**
* 遍历bean工厂后处理器集合,将不同的处理器添加分别添加到regularPostProcessors和registryProcessors集合中
* beanFactoryPostProcessors集合中存储的是用户自定义的后处理器类
* 有两种方式自定义:
* (1). 实现BeanDefinitionRegistryPostProcessor接口重写postProcessBeanDefinitionRegistry()方法和postProcessBeanFactory()方法, 还需要加@Component注解
* (2). 实现BeanFactoryPostProcessor接口重写postProcessBeanFactory()方法, 还需要加@Component注解
*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
//执行自定义实现BeanDefinitionRegistryPostProcessor接口的类中的postProcessBeanDefinitionRegistry()方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
/**
* 2. 将Spring内部的实现BeanDefinitionRegistryPostProcessor接口的根据优先级顺序执行 处理器类中重写该接口的postProcessBeanDefinitionRegistry()方法
* (实现PriorityOrdered接口的先执行,实现ordered接口的后执行,两者都没有实现的,最后执行)
*/
/**
* 将实现PriorityOrdered,Ordered等接口的BeanDefinitionRegistryPostProcessors分开按优先级执行
* 这个currentRegistryProcessors 存储的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
* 2.1 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor
* 根据BeanDefinitionRegistryPostProcessor.class获取所有实现BeanDefinitionRegistryPostProcessor接口的beanName;
* getBeanNamesForType()
* {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* 这个地方可以得到一个BeanFactoryPostProcessor(org.springframework.context.annotation.internalConfigurationAnnotationProcessor ->内部配置注解处理器),
* 因为是spring默认在最开始自己注册的,在下面的方法中注册的
* {@link AnnotationConfigUtils#registerAnnotationConfigProcessors()}
*
* 为什么要在最开始注册这个呢?
* 因为spring的工厂需要许解析去扫描等等功能,这些功能都是需要在spring工厂初始化完成之前执行
* 要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后; 因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
* 所以这里spring在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
* 在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
* (ConfigurationClassPostProcessor类的beanName为"org.springframework.context.annotation.internalConfigurationAnnotationProcessor")
*
* ConfigurationClassPostProcessor那么这个类能干嘛呢? ----> 很重要
* Spring使用ConfigurationClassPostProcessor完成对注解的扫描
* (1) ConfigurationClassPostProcessor调用postProcessBeanDefinitionRegistry()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
* (2) 在步骤四中ConfigurationClassPostProcessor调用postProcessBeanFactory()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, BeanDefinitionRegistry)}
*
*/
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//即将执行的BeanDefinitionRegistryPostProcessor类
processedBeans.add(ppName);
}
}
//根据PriorityOrdered接口设置的不同优先级进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
// 在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
registryProcessors.addAll(currentRegistryProcessors);
/**
* 循环遍历currentRegistryProcessors,.执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
* {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
* 该方法时BeanDefinitionRegistryPostProcessor接口继承BeanFactoryPostProcessor接口后增加的方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//currentRegistryProcessors集合中的类遍历执行完postProcessBeanDefinitionRegistry()方法后,清空该集合,以便后面进行重复使用
currentRegistryProcessors.clear();
/**
* 2.2 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessor
*/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// !processedBeans.contains(ppName) 如果processedBeans集合中已存在该beanName,那么说明已经执行过了,不需要再次执行
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//即将执行的BeanDefinitionRegistryPostProcessor类
processedBeans.add(ppName);
}
}
//根据Ordered接口设置的不同优先级进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
//在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
registryProcessors.addAll(currentRegistryProcessors);
//同上, 优先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor, 然后再执行实现Ordered接口的
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
/**
* 2.3 最后,执行其他没有实现PriorityOrdered接口和ordered接口的注册器后处理器类
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
//把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
registryProcessors.addAll(currentRegistryProcessors);
//同上, 该步骤执行没有实现PriorityOrdered接口和Ordered接口的处理器类的BeanDefinitionRegistryPostProcessor()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
/**
* 3. 执行所有处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的)的BeanFactoryPostProcessor方法
* 因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor接口,所以实现BeanDefinitionRegistryPostProcessor接口的处理器类也需要
* 重写BeanFactoryPostProcessor接口中的BeanFactoryPostProcessor方法
*
* 注意: registryProcessors中存储的是Spring内部和自定义实现BeanDefinitionRegistryPostProcessor接口的处理器类
* regularPostProcessors中存储的是自定义实现BeanFactoryPostProcessor接口的处理器类
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
// 如果该注册器是没有实现BeanDefinitionRegistry接口
else {
// 调用用上下文实例注册的工厂处理器
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/**
* 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
* 根据BeanFactoryPostProcessor类型获取到所有Spring内部实现BeanFactoryPostProcessor接口的处理器类的beanName
* {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//初始化存储实现PriorityOrdered接口的处理器的集合
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//初始化存储实现Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到orderedPostProcessors集合中
List<String> orderedPostProcessorNames = new ArrayList<>();
//初始化存储没有实现PriorityOrdered接口和Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//遍历postProcessorNames集合中所有的postProcessorName,从bean工厂中获取到相关的bean定义,存储在不同的集合中
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//注意此处存储的是beanName;
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
/**
* 4.1 执行实现PriorityOrdered接口的BeanFactoryPostProcessors处理器类
*/
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* 4.2 遍历orderedPostProcessorNames集合, 获取BeanDefinition存储到orderedPostProcessors集合中
* 然后执行实现Ordered接口的BeanFactoryPostProcessors处理器类
*/
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
/**
* 4.3 遍历nonOrderedPostProcessorNames集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
*/
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//清除缓存的合并bean定义,因为后处理器可能有修改原始元数据,例如替换值中的占位符…
beanFactory.clearMetadataCache();
}
分析: 这个方法很复杂, 也很重要; 大体上可以分为以下四个部分:
- 执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
- 执行Spring内部实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors
- 执行自定义实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
- 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
注: 这里仅介绍大体逻辑, 详细解析内容已在代码中标注; 对于使用ClassPathXmlApplicationContext初始化IOC容器, 一般情况下此处并没有执行任务Bean工厂后处理器, 并没有太大作用; 但是如果使用注解方式AnnotationConfigApplicationContext来初始化应用环境, 这里面将会激活一个bean工厂后处理器ConfigurationClassPostProcessor; Spring使用ConfigurationClassPostProcessor完成对注解的扫描, 相关内容在后面播客中会进行详细解析
5. 注册bean后处理处理器
_6. AbstractApplicationContext#registerBeanPostProcessors
==> PostProcessorRegistrationDelegate#registerBeanPostProcessors实现:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
/**
* BeanPostProcessorChecker是一个普通的信息打印,但是会出现一些请况:
* 当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时,便会打印出BeanPostProcessorChecker中设定的信息
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//使用priorityOrdered保证顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//使用Ordered保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//将bean处理器分类存储
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//第一步,注册所有实现了PriorityOrdered接口的BeanPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* {@link org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor)}
*/
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//第二步,注册所有实现Ordered的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//第三步,注册所有无序的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//第四步,注册所有MergedBeanDefinitionPostProcessors类型的BeanPostProcessor,并非重复注册
//在beanFactory.addBeanPostProcessor中会先移除已经存在的BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//添加ApplicationListener探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
分析: 先按照BeanPostProcessor.class从bean工厂中获取所有的Bean后处理器名称, 按照优先级对Bean后处理器进行注册
6. 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)
_11. AbstractApplicationContext#finishBeanFactoryInitialization实现:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
/**
* 实例化所有的单例对象
* {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons()}
*/
beanFactory.preInstantiateSingletons();
}
DefaultListableBeanFactory#preInstantiateSingletons实现:
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
/**
* 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
*/
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
/**
* 触发所有非惰性单例bean的初始化...
*/
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
/**
* 如果是工厂bean
*/
if (isFactoryBean(beanName)) {
//在beanName前加"&"前缀, 获取到FactoryBean (如果直接通过BeanName获取的则是getObject()方法返回的bean)
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//判断该bean对象是否是FactoryBean
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());
}
//只有isEagerInit值为true,才会在此时对FactoryBean进行初始化
if (isEagerInit) {
getBean(beanName);
}
}
}
/**
* 如果是普通bean
*/
else {
getBean(beanName);
}
}
}
/**
* 触发所有适用bean的初始化后回调...
* 如果目标Bean实现了SmartInitializingSingleton接口并重写了afterSingletonsInstantiated()方法,
* 这里将会执行该方法
*/
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
/**
* 执行afterSingletonsInstantiated()方法
*/
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
分析:
- 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
- 触发所有非惰性单例bean的初始化, 对工厂bean和普通bean区分处理
- 触发所有适用bean的初始化后的回调方法afterSingletonsInstantiated()
AbstractBeanFactory#getBean ==> AbstractBeanFactory#doGetBean
注: 关于Bean的初始化在后面播客会专门讲解, 这里不再分析了
7. 应用上下文刷新结束, 进行事件广播
_12. AbstractApplicationContext#finishRefresh实现:
protected void finishRefresh() {
//清除上下文级别的资源缓存(例如来自扫描的ASM元数据)
clearResourceCaches();
//为此上下文初始化生命周期处理器
initLifecycleProcessor();
//首先将刷新传播到生命周期处理器
getLifecycleProcessor().onRefresh();
/**
* 发布结束事件(事件对象:ContextRefreshedEvent)
*/
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
分析: 刷新结束后一些资源的清理以及生命周期的设置, 以及发布结束事件, 通知监听者Spring容器以及初始化完成, 观察者可以进行相关操作
至此, ClassPathXmlApplicationContext方式初始化容器解析完成;
相关文章:
Spring源码解析二 (IOC容器初始化方式一:XmlBeanFactory)
Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)
Spring源码解析四 (IOC容器初始化方式三: AnnotationConfigApplicationContext[包路径配置方式])
Spring源码解析五 (IOC容器初始化方式四: AnnotationConfigApplicationContext[Java配置类方式])