1. Spring架构设计
Spring框架是一个分层架构,他包含一系列的功能要素,并被分为大约20个模块
2. 设计理念
Spring是面向Bean的编程(BOP:Bean Oriented Programming),Bean在Spring中才是真正的主角。Bean在Spring中作用就像Object对OOP的意义一样,没有对象的概念就像没有面向对象编程,Spring中没有Bean也就没有Spring存在的意义。Spring提供了IoC 容器通过配置文件或者注解的方式来管理对象之间的依赖关系。
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。
3. 核心组件介绍
Bean组件
Bean组件定义在Spring的org.springframework.beans包下,解决了以下几个问题:
这个包下的所有类主要解决了三件事:
- Bean的定义
- Bean的创建
- Bean的解析
Spring Bean的创建是典型的工厂模式,它的顶级接口是BeanFactory。
BeanFactory有三个子类:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。目的是为了区分Spring内部对象处理和转化的数据限制。
但是从图中可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口
⭐Bean定义:BeanDefinition
这里的 BeanDefinition 就是我们所说的 Spring 的 Bean,我们自己定义的各个 Bean 其实会转换成一个个 BeanDefinition 存在于 Spring 的 BeanFactory 中
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
}
BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。
Context组件
Context在Spring的org.springframework.context包下
Context模块构建于Core和Beans模块基础之上,提供了一种类似于JNDI注册器的框架式的对象访问方法.Context模块继承了Beans的特性,为Spring核心提供了大量扩展,添加了对国际化(例如资源绑定)、事件传播、资源加载和对Context的透明创建的支持
ApplicationContext是Context的顶级父类
ApplicationContext 的子类主要包含两个方面:
- ConfigurableApplicationContext 表示该 Context 是可修改的,也就是在构建 Context 中用户可以动态添加或修改已有的配置信息
- WebApplicationContext 顾名思义,就是为 web 准备的 Context 他可以直接访问到 ServletContext,通常情况下,这个接口使用少
再往下分就是按照构建 Context 的文件类型,接着就是访问 Context 的方式。这样一级一级构成了完整的 Context 等级层次。
总体来说 ApplicationContext 必须要完成以下几件事:
- 标识一个应用环境
- 利用 BeanFactory 创建 Bean 对象
- 保存对象关系表
- 能够捕获各种事件
面试题:简述Spring后置处理器
后置处理器是一种拓展机制,贯穿Spring Bean的生命周期
后置处理器分为两类:
BeanFactory后置处理器:BeanFactoryPostProcessor
实现该接口,可以在spring的bean创建之前,修改bean的定义属性
public interface BeanFactoryPostProcessor {
/*
* 该接口只有一个方法postProcessBeanFactory,方法参数是ConfigurableListableBeanFactory,通过该
参数,可以获取BeanDefinition
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
Bean后置处理器:BeanPostProcessor
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口
实现该接口,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些处理逻辑
public interface BeanPostProcessor {
//bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
运行顺序
=Spring IOC容器实例化Bean=
=调用BeanPostProcessor的postProcessBeforeInitialization方法=
=调用bean实例的初始化方法=
=调用BeanPostProcessor的postProcessAfterInitialization方法=
⭐4. IOC流程图
⭐5. Bean的生命周期
Bean 生命周期的整个执行过程描述如下。
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法。
6. Spring源码环境构建
1. 自动化构建Gradle
引言:
从Sping5开始,官方就开始使用gradle来构建环境了
接下来,我们所有的环境都要基于gradle
1.1 什么是Gradle
Gradle是一个项目自动化构建工具。
是Apache的一个基于Ant 和Maven的软件,用于项目的依赖管理
项目的构建经历了三个时代:
Apache Ant(2000 年左右)
Maven(2004年)
Gradle(2012 年左右)
Spring(5.0开始) 等优秀的开源项目都将自己的项目从 Maven 迁移到了 Gradle
1.2 安装Gradle
-
Gradle下载地址:https://gradle.org/releases/
(注:需下载6.0以下版本,版本太高,会导致idea中编译时,部分spring组件无法下载)
- 解压:
-
环境变量配置
配置GRADLE_HOME:
配置Path:
- 执行 gradle -v 查看安装情况
- 在init.d文件夹下,创建init.gradle文件,编辑内容如下:(国内阿里云加速)
allprojects {
repositories {
//maven { url 'file:///Users/wangshouwen/.m2/repository'}
//mavenLocal()
maven { url 'https://maven.aliyun.com/repository/central'}
maven { url 'https://maven.aliyun.com/repository/jcenter'}
maven { url 'https://maven.aliyun.com/repository/public'}
maven { url 'https://maven.aliyun.com/repository/google'}
maven { url 'https://maven.aliyun.com/repository/gradle-plugin'}
maven { url 'https://maven.aliyun.com/repository/grails-core'}
maven { url 'https://maven.aliyun.com/repository/spring'}
maven { url 'https://maven.aliyun.com/repository/spring-plugin'}
maven { url 'https://maven.aliyun.com/repository/apache-snapshots'}
mavenCentral()
}
}
2. 下载Spring源码
2.1 下载
(GitHub): https://github.com/spring-projects/spring-framework
注意:对于源码要进行 git clone 拉取(如果直接下载zip,会报如下错误)
2.2 源码环境编译
进入bin目录下,执行 gradlew.bat(建议命令行中执行)
3 源码导入IDEA
使用import Project ( idea 2018)
直接open project (idea 2020)
漫长的等待…
(注意:手动配置JDK及gradle)
构建完成后,模块会出现蓝色小点
3. 构建源码测试模块
3.1 创建新Module
3.2 添加依赖
打开 build.gradle
dependencies {
compile(project(':spring-context')) // 添加spring-context依赖
compile(project(':spring-aop')) // 添加spring-aop依赖
testCompile group: 'junit', name: 'junit', version: '4.12'
}
3.3 编写测试代码
- 编写TestBean
@Component
public class TestBean {
public void print(){
System.err.println("testBean method...");
System.err.println("spring源码环境构建完成...");
}
}
- 创建applicationContext.xml,配置TestBean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testBean" class="com.demo.config.TestBean"/>
</beans>
- 编写测试类IOCTest
public class IOCTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestBean testBean = (TestBean) applicationContext.getBean("testBean");
testBean.print();
}
}
7. IOC 源码深度剖析
IOC容器初始化主流程
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestBean testBean = (TestBean) applicationContext.getBean("testBean");
testBean.print();
}
第一步,我们肯定要从 ClassPathXmlApplicationContext 的构造方法说起
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private Resource[] configResources;
// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
...
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
setConfigLocations(configLocations);
if (refresh) {
refresh(); // 核心方法
}
}
...
}
核心方法:refresh();
public void refresh() throws BeansException, IllegalStateException {
//加锁,防止多线程重复启动。
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//准备刷新
/*
【1.准备刷新】
(1) 设置容器的启动时间
(2) 设置活跃状态为true
(3) 设置关闭状态为false
(4) 获取Environment对象,并加载当前系统的属性值到Environment对象中
(5) 准备监听器和时间的集合对象,默认为空的集合
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/*
【2.初始化 新BeanFactory】重点!
(1)如果存在旧 BeanFactory,则销毁
(2)创建新的 BeanFactory(DefaluListbaleBeanFactory)
(3)解析xml/加载 Bean 定义、注册 Bean定义到beanFactory(不初始化)
(4)返回新的 BeanFactory(DefaluListbaleBeanFactory)
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 【3. bean工厂前置操作】为BeanFactory配置容器特性
// 例如类加载器、表达式解析器、注册默认环境bean、后置管理器BeanPostProcessor
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 【4. bean工厂后置操作】此处为空方法,如果子类需要,自己去实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//【5. 调用bean工厂后置处理器】,执行已注册的beanFactoryPostProcessor的实现类,在这里完成了类的扫描、解析和注册
//目标:
//调用顺序一:先bean定义 注册后置处理器
//调用顺序二:后bean工厂后置处理器
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//【6.注册bean后置处理器】只是注册,但是还不会调用
//逻辑:找出所有实现BeanPostProcessor接口的类,分类、排序、注册
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//【7.初始化消息源】国际化问题i18n
initMessageSource();
// Initialize event multicaster for this context.
//【8、初始化事件广播器】初始化自定义的事件监听多路广播器
// 如果需要发布事件,就调它的multicastEvent方法
// 把事件广播给listeners,其实就是起一个线程来处理,把Event扔给listener处理
// (可以通过 SimpleApplicationEventMulticaster的代码来验证)
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 【9、刷新:拓展方法】这是个protected空方法,交给具体的子类来实现
// 可以在这里初始化一些特殊的 Bean
onRefresh();
// Check for listener beans and register them.
//【10、注册监听器】,监听器需要实现 ApplicationListener 接口
// 也就是扫描这些实现了接口的类,给他放进广播器的列表中
// 其实就是个观察者模式,广播器接到事件的调用时,去循环listeners列表,
// 挨个调它们的onApplicationEvent方法,把event扔给它们。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
///【11、 实例化所有剩余的(非惰性初始化)单例】
// (1)初始化所有的 singleton beans,反射生成对象/填充
// (2)调用Bean的前置处理器和后置处理器
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 【12、结束refresh操作】
// 发布事件与清除上下文环境
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//清除反射的类数据,注解数据等。
resetCommonCaches();
}
}
}
【1.准备刷新 】prepareRefresh();
方法概述
为刷新准备新的上下文环境,设置其启动日期和活动标志以及执行一些属性的初始化。主要是一些准备工作(不是很重要的方法)
源码剖析
prepareRefresh();
protected void prepareRefresh() {
// 记录启动时间,
// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();
// 会创建StandardEnvironment对象 校验 xml 配置文件
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
【2.初始化 BeanFactory 】obtainFreshBeanFactory(); 重点!
方法概述
作用:用于获得一个新的 BeanFactory
流程:该方法会解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中(只注册,不会进行Bean的实例化)。
常见的,如果解析到<context:component-scan base-package=“com.demo” /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的 bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。
上面提到的“加载到 BeanFactory 中”的内容主要指的是以下3个缓存(map):(Bean并没有实例化)
- beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
- beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射。
- aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。
源码剖析
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 1.刷新(创建) BeanFactory,由AbstractRefreshableApplicationContext实现
refreshBeanFactory();
// 2.拿到刷新后的 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
1.刷新 BeanFactory,由 AbstractRefreshableApplicationContext 实现,见代码块1详解。
代码块1:refreshBeanFactory 方法
@Override
protected final void refreshBeanFactory() throws BeansException {
// 1.判断是否已经存在 BeanFactory,如果存在则先销毁、关闭该 BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 2.创建一个新的BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 用于 BeanFactory 的序列化,大部分人应该都用不到
beanFactory.setSerializationId(getId());
// 重要:设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
customizeBeanFactory(beanFactory);
// 3.重要:加载 Bean 到 BeanFactory 中
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
BeanDefinition 接口
BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 我们可以看到,默认只提供 sington 和 prototype 两种,
// 还有 request, session, globalSession, application, websocket 这几种,
// 不过,它们属于基于 web 的扩展。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 比较不重要,直接跳过吧
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。请参见附录的详细介绍
// 一句话就是:继承父 Bean 的配置信息而已
void setParentName(String parentName);
// 获取父 Bean
String getParentName();
// 设置 Bean 的类名称,将来是要通过反射来生成实例的
void setBeanClassName(String beanClassName);
// 获取 Bean 的类名称
String getBeanClassName();
// 设置 bean 的 scope
void setScope(String scope);
String getScope();
// 设置是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的),
// 是 depends-on="" 属性设置的值。
void setDependsOn(String... dependsOn);
// 返回该 Bean 的所有依赖
String[] getDependsOn();
// 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效,
// 如果根据名称注入,即使这边设置了 false,也是可以的
void setAutowireCandidate(boolean autowireCandidate);
// 该 Bean 是否可以注入到其他 Bean 中
boolean isAutowireCandidate();
// 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
void setPrimary(boolean primary);
// 是否是 primary 的
boolean isPrimary();
// 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录
// 一句话就是:有些实例不是用反射生成的,而是用工厂模式生成的
void setFactoryBeanName(String factoryBeanName);
// 获取工厂名称
String getFactoryBeanName();
// 指定工厂类中的 工厂方法名称
void setFactoryMethodName(String factoryMethodName);
// 获取工厂类中的 工厂方法名称
String getFactoryMethodName();
// 构造器参数
ConstructorArgumentValues getConstructorArgumentValues();
// Bean 中的属性值,后面给 bean 注入属性值的时候会说到
MutablePropertyValues getPropertyValues();
// 是否 singleton
boolean isSingleton();
// 是否 prototype
boolean isPrototype();
// 如果这个 Bean 是被设置为 abstract,那么不能实例化,
// 常用于作为 父bean 用于继承,其实也很少用......
boolean isAbstract();
int getRole();
String getDescription();
String getResourceDescription();
BeanDefinition getOriginatingBeanDefinition();
}
有了 BeanDefinition 的概念以后,我们再往下看 refreshBeanFactory() 方法中的剩余部分:
📌customizeBeanFactory()
customizeBeanFactory(beanFactory) 比较简单,就是配置是否允许 BeanDefinition 覆盖、是否允许循环引用。
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
// 是否允许 Bean 定义覆盖
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
// 是否允许 Bean 间的循环依赖
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
是否允许 Bean 定义覆盖:
allowBeanDefinitionOverriding 属性为 null,如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。
是否允许 Bean 间的循环依赖:
A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。
默认情况下,Spring 允许循环依赖
3.加载 bean 定义,由 XmlWebApplicationContext 实现,见代码块2详解。
代码块2:loadBeanDefinitions
/** 我们可以看到,此方法将通过一个 XmlBeanDefinitionReader 实例来加载各个 Bean。*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1.为指定BeanFactory创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
// 2.使用此上下文的资源加载环境配置 XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
// resourceLoader赋值为XmlWebApplicationContext
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化 BeanDefinitionReader,其实这个是提供给子类覆写的,
initBeanDefinitionReader(beanDefinitionReader);
// 3.加载 bean 定义 重点
loadBeanDefinitions(beanDefinitionReader);
}
3.加载 bean 定义,见代码块3详解。
代码块3:loadBeanDefinitions
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 1.获取配置文件路径
Resource[] configResources = getConfigResources();
if (configResources != null) {
// 往下看
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 2.根据配置文件路径加载 bean 定义
reader.loadBeanDefinitions(configLocations);
}
}
// AbstractRefreshableWebApplicationContext.java
@Override
public String[] getConfigLocations() {
return super.getConfigLocations();
}
// AbstractRefreshableConfigApplicationContext.java
protected String[] getConfigLocations() {
return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
}
// XmlWebApplicationContext.java
@Override
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null) {
return new String[]{DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
} else {
return new String[]{DEFAULT_CONFIG_LOCATION};
}
}
1.获取配置文件路径:如果 configLocations 属性不为空,则返回 configLocations 的值;否则,调用 getDefaultConfigLocations() 方法。获取到配置文件路径(Spring 默认的配置路径:/WEB-INF/applicationContext.xml。)
2.根据配置文件路径加载 bean 定义,见代码块4详解。
代码块4:loadBeanDefinitions
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
// 1.遍历所有的Resource
for (Resource resource : resources) {
// 2.根据Resource加载bean的定义,XmlBeanDefinitionReader实现
counter += loadBeanDefinitions(resource);
}
return counter;
}
2.根据 Resource 加载 bean 定义,由 XmlBeanDefinitionReader 实现,见代码块5详解。
方法块5:loadBeanDefinitions
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 加载 bean 定义
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
// 1.当前正在加载的EncodedResource
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
// 2.将当前encodedResource添加到currentResources
if (!currentResources.add(encodedResource)) {
// 如果添加失败,代表当前的encodedResource已经存在,则表示出现了循环加载
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
// 3.拿到Resource的inputStream
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
// 4.将inputStream封装成org.xml.sax.InputSource
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 5.加载 bean 定义(方法以do开头,真正处理的方法)
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
5.加载 bean 定义,方法以 do 开头,真正处理的方法,见代码块6详解。
代码块6:doLoadBeanDefinitions
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 1.根据inputSource和resource加载XML文件,并封装成Document
Document doc = doLoadDocument(inputSource, resource);
// 2.根据返回的Document注册Bean信息(对配置文件的解析,核心逻辑)
return registerBeanDefinitions(doc, resource);
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
} catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
} catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
} catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
1.根据 inputSource 和 resource 加载 XML文件,并封装成 Document,见代码块7详解。
2.根据返回的 Document 注册 bean 数量,见代码块8详解。
代码块7:doLoadDocument
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
// 1.getValidationModeForResource(resource): 获取XML配置文件的验证模式
// 2.documentLoader.loadDocument: 加载XML文件,并得到对应的 Document
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
protected int getValidationModeForResource(Resource resource) {
int validationModeToUse = getValidationMode();
// 1.1 如果手动指定了XML文件的验证模式则使用指定的验证模式
if (validationModeToUse != VALIDATION_AUTO) {
return validationModeToUse;
}
// 1.2 如果未指定则使用自动检测
int detectedMode = detectValidationMode(resource);
// 1.3 如果检测出的验证模式不为 VALIDATION_AUTO, 则返回检测出来的验证模式
if (detectedMode != VALIDATION_AUTO) {
return detectedMode;
}
// Hmm, we didn't get a clear indication... Let's assume XSD,
// since apparently no DTD declaration has been found up until
// detection stopped (before finding the document's root tag).
// 1.4 如果最终没找到验证模式,则使用 XSD
return VALIDATION_XSD;
}
protected int detectValidationMode(Resource resource) {
// 1.2.1 校验resource是否为open stream
if (resource.isOpen()) {
throw new BeanDefinitionStoreException(
"Passed-in Resource [" + resource + "] contains an open stream: " +
"cannot determine validation mode automatically. Either pass in a Resource " +
"that is able to create fresh streams, or explicitly specify the validationMode " +
"on your XmlBeanDefinitionReader instance.");
}
InputStream inputStream;
try {
// 1.2.2 校验resource是否可以打开InputStream
inputStream = resource.getInputStream();
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " +
"Did you attempt to load directly from a SAX InputSource without specifying the " +
"validationMode on your XmlBeanDefinitionReader instance?", ex);
}
try {
// 1.2.3 根据inputStream检测验证模式
return this.validationModeDetector.detectValidationMode(inputStream);
} catch (IOException ex) {
throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +
resource + "]: an error occurred whilst reading from the InputStream.", ex);
}
}
public int detectValidationMode(InputStream inputStream) throws IOException {
// Peek into the file to look for DOCTYPE.
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
boolean isDtdValidated = false;
String content;
// 1.2.3.1 按行遍历xml配置文件,获取xml文件的验证模式
while ((content = reader.readLine()) != null) {
content = consumeCommentTokens(content);
// 如果读取的行是空或者注释则略过
if (this.inComment || !StringUtils.hasText(content)) {
continue;
}
// 内容包含"DOCTYPE"则为DTD,否则为XSD
if (hasDoctype(content)) {
isDtdValidated = true;
break;
}
// 如果content带有 '<' 开始符号,则结束遍历。因为验证模式一定会在开始符号之前,所以到此可以认为没有验证模式
if (hasOpeningTag(content)) {
// End of meaningful data...
break;
}
}
// 1.2.3.2 根据遍历结果返回验证模式是 DTD 还是 XSD
return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
} catch (CharConversionException ex) {
// Choked on some character encoding...
// Leave the decision up to the caller.
return VALIDATION_AUTO;
} finally {
reader.close();
}
}
// DefaultDocumentLoader.java
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
// 2.1 创建DocumentBuilderFactory
DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
if (logger.isDebugEnabled()) {
logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
}
// 2.2 通过DocumentBuilderFactory创建DocumentBuilder
DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
// 2.3 使用DocumentBuilder解析inputSource返回Document对象
return builder.parse(inputSource);
}
1.获取 XML 配置文件的验证模式。XML 文件的验证模式是用来保证 XML 文件的正确性,常见的验证模式有两种:DTD 和 XSD,以下简单展示下这两种验证模式的配置。
DTD 验证模式(已停止更新)
要使用 DTD 验证模式的时候需要在 XML 文件的头部声明,以下是在 Spring 中使用 DTD 声明方式的代码:
XSD 验证模式
代码块8:registerBeanDefinitions
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 1.使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 2.记录统计前BeanDefinition的加载个数
int countBefore = getRegistry().getBeanDefinitionCount();
// 3.createReaderContext:根据resource创建一个XmlReaderContext
// 4.registerBeanDefinitions:加载及注册Bean定义
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 5.返回本次加载的BeanDefinition个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
4.加载及注册 bean 定义,由 DefaultBeanDefinitionDocumentReader 实现,见代码块9详解。
代码块9:registerBeanDefinitions
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
// 1.拿到文档的子节点,对于Spring的配置文件来说,理论上应该都是<beans>
Element root = doc.getDocumentElement();
// 2.通过拿到的节点,注册 Bean 定义
doRegisterBeanDefinitions(root);
}
2.通过拿到的节点,注册 bean 定义,见代码块10详解。
代码块10:doRegisterBeanDefinitions
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
// 构建BeanDefinitionParserDelegate
this.delegate = createDelegate(getReaderContext(), root, parent);
// 1.校验root节点的命名空间是否为默认的命名空间(默认命名空间http://www.springframework.org/schema/beans)
if (this.delegate.isDefaultNamespace(root)) {
// 2.处理profile属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// 校验当前节点的 profile 是否符合当前环境定义的, 如果不是则直接跳过, 不解析该节点下的内容
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
// 3.解析前处理, 留给子类实现
preProcessXml(root);
// 4.解析并注册bean定义
parseBeanDefinitions(root, this.delegate);
// 5.解析后处理, 留给子类实现
postProcessXml(root);
this.delegate = parent;
}
4.解析并注册 bean 定义,见代码块11详解。
代码块11:parseBeanDefinitions
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 1.默认命名空间的处理
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
// 遍历root的子节点列表
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)) {
// 1.1 默认命名空间节点的处理,例如: <bean id="test" class="" />
parseDefaultElement(ele, delegate);
}
else {
// 1.2 自定义命名空间节点的处理,例如:<context:component-scan/>、<aop:aspectj-autoproxy/>
delegate.parseCustomElement(ele);
}
}
}
} else {
// 2.自定义命名空间的处理
delegate.parseCustomElement(root);
}
}
最终,我们来到了解析 bean 定义的核心部分,这边会遍历 root 节点(正常为 节点)下的所有子节点,对子节点进行解析处理。
如果节点的命名空间是 Spring 默认的命名空间,则走 parseDefaultElement(ele, delegate) 方法进行解析,例如最常见的:。
如果节点的命名空间不是 Spring 默认的命名空间,也就是自定义命名空间,则走 delegate.parseCustomElement(ele) 方法进行解析,例如常见的: context:component-scan、aop:aspectj-autoproxy。
如何判断默认命名空间还是自定义命名空间?
默认的命名空间为:http://www.springframework.org/schema/beans,其他都是自定义命名空间,
例如下图 aop 的命名空间为:http://www.springframework.org/schema/aop
// 1.1 默认命名空间节点的处理,例如:
parseDefaultElement(ele, delegate);
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 1.对import标签的处理
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// 2.对alias标签的处理
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// 3.对bean标签的处理(最复杂最重要)
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
// 4.对beans标签的处理
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
可以看到默认命名空间的一级节点只有4种:import、alias、bean、beans, 主要看bean节点
另外, 其他节点只是递归调用之前的 doRegisterBeanDefinitions 方法,因此无需再介绍。
processBeanDefinition
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 1.进行节点定义解析, 经过这个方法后,bdHolder会包含一个Bean节点的所有属性,例如name、class、id
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 2.若存在默认标签的子节点下再有自定义属性,需要再次对自定义标签再进行解析(基本不用,不做深入解析)
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 3.解析节点定义完成后,需要对解析后的bdHolder进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// 4.最后发出响应事件,通知相关的监听器,这个Bean已经加载完成了
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
- 进行节点定义解析,见代码块1详解。
- 基本不用,不做深入解析。
- 解析节点定义完成后,需要对解析后的 bdHolder 进行注册,见代码块13详解。
- 发出响应事件,通知相关的监听器,不做深入解析。
代码块1:parseBeanDefinitionElement
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
// 1.解析name和id属性
// 解析id属性
String id = ele.getAttribute(ID_ATTRIBUTE);
// 解析name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// 分割name属性(通过逗号或分号)
// 例如:<bean name="demoService,demoServiceAlias" class=""/>,分割后aliases为[demoService, demoServiceAlias]
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
// beanName默认使用id
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
// 如果id为空,并且aliases不为空,则取aliases的第一个元素作为beanName,其他的仍作为别名
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
// 检查beanName和aliases是否在同一个 <beans> 下已经存在
checkNameUniqueness(beanName, aliases, ele);
}
// 2.进一步解析bean的其他所有属性并统一封装至GenericBeanDefinition类型实例中
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
// 3.如果bean定义存在,但是beanName为空,则用Spring默认的生成规则为当前bean生成beanName
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
// Spring提供的生成规则生成beanName,例如:com.demo.demo.service.impl.DemoServiceImpl#0
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
// 如果Spring默认的生成规则生成的beanName为:类名加后缀,则将类名注册为别名
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
// 4.将bean定义、beanName、bean别名数组封装成BeanDefinitionHolder
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
1.解析 name 和 id 属性,其中 name 属性可以通过分割符设置多个。如果 id 存在,则 使用 id 作为 beanName,name 属性分割后全部作为别名;如果 id 不存在,则将 name 属性分割后的第1个作为 beanName,剩下的全部作为别名。
举个例子:
<!-- 配置1 -->
<bean id="appleService" name="appleOne;appleTwo" class="com.demo.AppleServiceImpl"/>
<!-- 配置2 -->
<bean name="bananaOne;bananaTwo" class="com.demo.BananaServiceImpl"/>
2.进一步解析 bean 的其他所有属性并统一封装至 GenericBeanDefinition 类型实例中,见代码块2详解。
代码块2:parseBeanDefinitionElement
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
// 1.解析class、parent属性
// 解析class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
// 解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
// 2.创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 3.解析bean的各种属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 提取description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析元数据子节点(基本不用, 不深入介绍)
parseMetaElements(ele, bd);
// 解析lookup-method子节点(基本不用, 不深入介绍)
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析replaced-method子节点(基本不用, 不深入介绍)
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 4.解析constructor-arg子节点
parseConstructorArgElements(ele, bd);
// 5.解析property子节点
parsePropertyElements(ele, bd);
// 解析qualifier子节点(基本不用, 不深入介绍)
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
1.解析了class、parent属性,因为第2步创建 AbstractBeanDefinition 需要用到这两个属性,否则,这两个属性可以放到第3步一起解析。
2.创建用于承载属性的 AbstractBeanDefinition 类型的 GenericBeanDefinition。比较简单,直接 new 一个 GenericBeanDefinition,如果 className 和 classLoader 不为空,则通过反射构建出 BeanClass,并设置为 GenericBeanDefinition 的属性。
3.解析 bean 的剩余属性,见代码块3详解。
4.解析 constructor-arg 子节点
5.解析 property 子节点,见代码块4详解。
代码块3:parseBeanDefinitionAttributes
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
BeanDefinition containingBean, AbstractBeanDefinition bd) {
// 解析singleton属性
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
// singleton属性已经不支持, 如果使用了会直接抛出异常, 请使用scope属性代替
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// 解析scope属性
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
}
// 解析abstract属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// 解析lazy-init属性, 默认为false
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
// 解析autowire属性
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
// 解析dependency-check属性
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
// 解析depends-on属性
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
// 解析autowire-candidate属性
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
// 解析primary属性
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
// 解析init-method属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.setInitMethodName(initMethodName);
}
}
else {
if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
}
// 解析destroy-method属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
bd.setDestroyMethodName(destroyMethodName);
}
else {
if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
}
// 解析factory-method属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
// 解析factory-bean属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
内容比较简单,就是从节点 ele 拿到所有的属性值,塞给 AbstractBeanDefinition 的对应属性。这些属性的使用如下图。
代码块4:parsePropertyElements
public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
// 拿到beanEle节点的所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
// 解析property节点
parsePropertyElement((Element) node, bd);
}
}
}
拿到 beanEle 节点的所有子节点,遍历解析所有是 property 节点的子节点,见代码块5详解。
property 的使用如下图所示,property 节点类似于set方法,bean 中的属性必须要有 set 方法才可以使用,否则会报错。
代码块5:parsePropertyElement
public void parsePropertyElement(Element ele, BeanDefinition bd) {
// 1.拿到name属性
String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
if (!StringUtils.hasLength(propertyName)) {
// name属性为必要属性,如果没有配置,则抛出异常
error("Tag 'property' must have a 'name' attribute", ele);
return;
}
this.parseState.push(new PropertyEntry(propertyName));
try {
// 2.校验在相同bean节点下,是否存在相同的name属性,如果存在则抛出异常
if (bd.getPropertyValues().contains(propertyName)) {
error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
return;
}
// 3.解析属性值
Object val = parsePropertyValue(ele, bd, propertyName);
// 4.将解析的属性值和属性name封装成PropertyValue
PropertyValue pv = new PropertyValue(propertyName, val);
// 5.解析meta节点(基本不用,不深入解析)
parseMetaElements(ele, pv);
pv.setSource(extractSource(ele));
// 6.将解析出来的PropertyValue,添加到BeanDefinition的propertyValues属性中(上面的重复校验用到)
bd.getPropertyValues().addPropertyValue(pv);
}
finally {
this.parseState.pop();
}
}
代码块6:registerBeanDefinition
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
// 1.拿到beanName
String beanName = definitionHolder.getBeanName();
// 2.注册beanName、BeanDefinition到缓存中(核心逻辑),实现类为; DefaultListableBeanFactory
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
// 注册bean名称的别名(如果有的话)
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
// 3.注册bean的beanName和对应的别名映射到缓存中(缓存:aliasMap)
registry.registerAlias(beanName, alias);
}
}
}
2.注册 beanName、BeanDefinition 到缓存中,见代码块7详解。
3.如果有别名,则注册 bean 的 beanName 和对应的别名映射到 aliasMap 缓存中,见代码块9详解。
代码块7:registerBeanDefinition
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 1.beanName和beanDefinition为空校验
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// 注册前的最后校验
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
// 首先根据beanName从beanDefinitionMap缓存中尝试获取
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
// 2.beanName存在于缓存中
if (!isAllowBeanDefinitionOverriding()) {
// 如果不允许相同beanName重新注册,则直接抛出异常
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
} else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
} else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存(以供后续创建bean时使用)
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
// 3.beanName不存在于缓存中
if (hasBeanCreationStarted()) {
// 3.1 bean创建阶段已经开始
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将本次传进来的beanName 加入beanDefinitionNames缓存
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 将beanName从manualSingletonNames缓存移除
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
// 3.2 bean创建阶段还未开始
// Still in startup registration phase
// 将本次传进来的beanName 和 BeanDefinition映射放入beanDefinitionMap缓存
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将本次传进来的beanName 加入beanDefinitionNames缓存
this.beanDefinitionNames.add(beanName);
// 将beanName从manualSingletonNames缓存移除
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 4.如果存在相同beanName的BeanDefinition,并且beanName已经存在单例对象,则将该beanName对应的缓存信息、单例对象清除,
// 因为这些对象都是通过oldBeanDefinition创建出来的,需要被覆盖掉的,
// 我们需要用新的BeanDefinition(也就是本次传进来的beanDefinition)来创建这些缓存和单例对象
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
这个方法会将 beanName 添加到 beanDefinitionNames 缓存,将 beanName 和 BeanDefinition 的映射关系添加到beanDefinitionMap 缓存。
如果 beanName不重复(一般不会重复),对于我们当前正在解析的 obtainFreshBeanFactory 方法来说,因为 bean 创建还未开始,因此会走到 3.2 进行缓存的注册。
4.如果 beanName 重复,并且该 beanName 已经存在单例对象,则会调用 resetBeanDefinition 方法,见代码块8详解。
代码块8:resetBeanDefinition
protected void resetBeanDefinition(String beanName) {
// Remove the merged bean definition for the given bean, if already created.
// 1.删除beanName的mergedBeanDefinitions缓存(如果有的话)
clearMergedBeanDefinition(beanName);
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
// be necessary, rather just meant for overriding a context's default beans
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
// 2.从单例缓存中删除该beanName对应的bean(如果有的话)
destroySingleton(beanName);
// Reset all bean definitions that have the given bean as parent (recursively).
// 3.重置beanName的所有子Bean定义(递归)
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
// 当前遍历的BeanDefinition的parentName为beanName,则递归调用resetBeanDefinition进行重置
if (beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
}
}
比较简单,将该 beanName 的 mergedBeanDefinitions 缓存信息删除、单例缓存删除。如果存在子 bean 定义,则递归重置。实际开发过程中,基本不会出现 beanName 相同的情况,因此基本不会走到该方法。
代码块9:registerAlias
@Override
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
// 1.如果别名和beanName相同,则不算别名,从aliasMap缓存中移除
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
// 2.如果别名已经注册过,直接返回
return;
}
// 3.如果存在相同的别名,并且不允许别名覆盖,则抛出异常
if (!allowAliasOverriding()) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
// 4.检查name和alias是否存在循环引用。例如A的别名为B,B的别名为A
checkForAliasCircle(name, alias);
// 5.将别名和beanName的映射放到aliasMap缓存中
this.aliasMap.put(alias, name);
}
}
将别名和 beanName 注册到 aliasMap 缓存。
方法总结
到这里已经初始化了 Bean 容器,<bean />
配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到注册中心,并且发送了注册事件
- 首先,将 xml 中的 bean 配置信息进行了解析,并构建了 AbstractBeanDefinition(GenericBeanDefinition) 对象来存放所有解析出来的属性
- 其次,将 AbstractBeanDefinition 、beanName、aliasesArray 构建成 BeanDefinitionHolder 对象并返回
- 最后,通过 BeanDefinitionHolder 将 BeanDefinition 和 beanName 注册到 BeanFactory 中,也就是存放到缓存中。
执行完 parseDefaultElement 方法,我们得到了两个重要的缓存:
- beanDefinitionNames 缓存
- beanDefinitionMap 缓存
【3. bean工厂前置操作】prepareBeanFactory(beanFactory)
方法概述
配置 beanFactory 的标准上下文特征,例如上下文的 ClassLoader、后置处理器等。这个方法会注册3个默认环境 bean:environment、systemProperties 和 systemEnvironment,注册 2 个 bean 后置处理器:ApplicationContextAwareProcessor 和 ApplicationListenerDetector。
源码剖析
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置 BeanFactory 的类加载器 BeanFactory 需要加载类,也就需要类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//设置属性注册解析器PropertyEditor
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 添加一个 BeanPostProcessor,这个 processor 比较简单:
// 实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调,
// 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
// 注意:它不仅仅回调 ApplicationContextAware,还会负责回调 EnvironmentAware、ResourceLoaderAware 等
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略依赖接口
// skip:下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,
// Spring 会通过其他方式来处理这些依赖。
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.
/*
* skip:下面几行就是为特殊的几个 bean 赋值,如果有 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.
// 这个 BeanPostProcessor 也很简单,在 bean 实例化后,如果是 ApplicationListener 的子类,
// 那么将其添加到 listener 列表中,可以理解成:注册 事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//*****************************智能注册***************************************************
//如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,
// 这里涉及到特殊的 bean,名为:loadTimeWeaver,这不是我们的重点,忽略它
// tips: ltw 是 AspectJ 的概念,指的是在运行期进行织入,这个和 Spring AOP 不一样,
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()));
}
// Register default environment beans.
/**
* 从下面几行代码我们可以知道,Spring 往往很 "智能" 就是因为它会帮我们默认注册一些有用的 bean,
* 我们也可以选择覆盖
*/
// 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 如果没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 如果没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
📌【4. bean工厂后置操作】postProcessBeanFactory(beanFactory)
此处为空方法,如果子类需要,自己去实现
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
【5. 调用bean工厂后置处理器】invokeBeanFactoryPostProcessors(beanFactory);
方法概述
- 该方法会 实例化 和 调用 所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
- BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
- BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
实例演示
📌1.BeanDefinitionRegistryPostProcessor 的扩展使用
使用方法比较简单,新建一个类实现 BeanDefinitionRegistryPostProcessor 接口,并将该类注册到 Spring IoC 容器中。
package com.demo.BeanFactoryPostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
// 自己的逻辑处理
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
// 自己的逻辑处理
}
@Override
public int getOrder() {
return 0;
}
}
📌2.BeanFactoryPostProcessor 的扩展使用
使用方法跟 BeanDefinitionRegistryPostProcessor 类似。
package com.demo.BeanFactoryPostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory");
// 自己的逻辑处理
}
}
源码剖析
invokeBeanFactoryPostProcessors(beanFactory);
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
-
- 拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,见代码块1详解。
-
- 实例化并调用所有已注册的 BeanFactoryPostProcessor,见代码块2详解。
代码块1:getBeanFactoryPostProcessors
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。
如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量?
在prepareBeanFactory#customizeContext 方法,该方法是 Spring 提供给开发者的一个扩展点,用于自定义应用上下文,并且在 refresh() 方法前就被调用。在这边就可以通过该方法来添加自定义的 BeanFactoryPostProcessor。
简单的实现如下:
1.新建一个 ApplicationContextInitializer 的实现类 SpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。
package com.demo.spring;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
public class SpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
// 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
// ...自定义操作
System.out.println("SpringApplicationContextInitializer#initialize");
}
}
2.将 SpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>
com.demo.spring.SpringApplicationContextInitializer
</param-value>
</context-param>
这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors 中。
代码块2:invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 1. 判断beanFactory是否为BeanDefinitionRegistry
// beanFactory类型为DefaultListableBeanFactory,DefaultListableBeanFactory实现了BeanDefinitionRegistry,所有为true
if (beanFactory instanceof BeanDefinitionRegistry) {
// 类型强转
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 声明集合:保存普通的BeanFactoryPostProcessor类型的后置处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 声明集合:保存BeanDefinitionRegistryPostProcessor类型的后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 2.首先遍历处理入参中的BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 2.1 如果是BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 2.1.1 执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
}
else {
// 2.2 否则,只是普通的BeanFactoryPostProcessor
// 2.2.1 添加到regularPostProcessors集合
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 定义集合:用于保存本次要执行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 3.调用所有实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
// 3.1 找出所有实现了PriorityOrdered接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 3.2 遍历postProcessorNames
for (String ppName : postProcessorNames) {
// 3.3 校验是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 获取ppName对应的bean实例,添加到currentRegistryProcessors
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 3.5 将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 执行完毕后, 清空currentRegistryProcessors
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
// 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 校验是否实现了Ordered接口,并且还未执行过
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 5.2 跳过已经执行过的
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
// 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
// 因此这边将reiterate赋值为true, 代表需要再循环查找一次
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
// 下面开始处理容器中的所有BeanFactoryPostProcessor
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 8.找出所有实现BeanFactoryPostProcessor接口的类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
// 用于存放普通BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
for (String ppName : postProcessorNames) {
// 8.2 跳过已经执行过的
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
}
else {
// 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 9.首先,调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
// 9.1 对priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 10.下一步,调用所有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
// 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 10.2 对orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 11.调用所有剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
beanFactory.clearMetadataCache();
}
1.判断 beanFactory 是否为 BeanDefinitionRegistry。beanFactory 是在之前的 obtainFreshBeanFactory 方法构建的,具体代码在:AbstractRefreshableApplicationContext.refreshBeanFactory() 方法,代码如下。
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建一个新的BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
可以看出,我们构建的 beanFactory 是一个 DefaultListableBeanFactory ,而 DefaultListableBeanFactory 实现了BeanDefinitionRegistry 接口,因此 beanFactory instanceof BeanDefinitionRegistry 结果为 true。
3.4 获取 ppName 对应的 bean 实例,添加到 currentRegistryProcessors 中,准备执行。beanFactory.getBean 方法会触发创建 ppName 对应的 bean 实例对象,创建 bean 实例是 IoC 的另一个核心内容,之后会单独解析,目前暂不深入解析。
3.6 进行排序,该方法在下面也被调用了好几次,见代码块3详解。
代码块3:sortPostProcessors
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
// 1.获取设置的比较器
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
// 2.如果没有设置比较器, 则使用默认的OrderComparator
comparatorToUse = OrderComparator.INSTANCE;
}
// 3.使用比较器对postProcessors进行排序
Collections.sort(postProcessors, comparatorToUse);
}
方法总结
- 整个 invokeBeanFactoryPostProcessors 方法围绕两个接口,BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor,其中 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 。
- BeanDefinitionRegistryPostProcessor 主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 Bean 定义,说的简单点,就是 BeanDefinitionRegistryPostProcessor 具有更高的优先级,执行顺序在 BeanFactoryPostProcessor 之前。
- 该方法就是完成了实例化并调用了所有的BeanFactoryPostProcessor
📌【6. 注册Bean后置处理器】registerBeanPostProcessors(beanFactory);
方法描述
方法作用:会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类注册到 BeanFactory 中。
- BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点
- 在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。
注意:在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。
实例演示
新建一个类实现 BeanPostProcessor 接口,并将该类注册到 Spring IoC 容器中。
package com.demo.BeanPostProcessor;
import com.demo.demo.service.UserService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization");
if (bean instanceof UserService) {
System.out.println(beanName);
}
// 自己的逻辑
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor#postProcessAfterInitialization");
// 自己的逻辑
return bean;
}
@Override
public int getOrder() {
return 0;
}
}
这样,在 Spring 创建 bean 实例时,执行初始化方法前会调用 MyBeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用 MyBeanPostProcessor 的 postProcessAfterInitialization 方法。
源码剖析
registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.注册BeanPostProcessor
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
1.注册 BeanPostProcessor,见代码块1详解。
代码块1:registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1.找出所有实现BeanPostProcessor接口的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// BeanPostProcessor的目标计数
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
// 3.1 priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
// 3.2 internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
// 3.3 orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 3.4 nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 4.遍历postProcessorNames, 将BeanPostProcessors按3.1 - 3.4定义的变量区分开
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 4.1 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 4.2 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 4.3 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames
orderedPostProcessorNames.add(ppName);
}
else {
// 4.4 否则, 将ppName添加到nonOrderedPostProcessorNames
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 5.首先, 注册实现PriorityOrdered接口的BeanPostProcessors
// 5.1 对priorityOrderedPostProcessors进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 5.2 注册priorityOrderedPostProcessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 6.接下来, 注册实现Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
// 6.1 拿到ppName对应的BeanPostProcessor实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 6.2 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 6.3 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
// 6.4 对orderedPostProcessors进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 6.5 注册orderedPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 7.注册所有常规的BeanPostProcessors(过程与6类似)
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
// 8.1 对internalPostProcessors进行排序
sortPostProcessors(internalPostProcessors, beanFactory);
// 8.2注册internalPostProcessors
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
5.2 注册 priorityOrderedPostProcessors,见代码块2详解。
代码块2:registerBeanPostProcessors
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
// 1.遍历postProcessors
for (BeanPostProcessor postProcessor : postProcessors) {
// 2.将PostProcessor添加到BeanFactory中的beanPostProcessors缓存
beanFactory.addBeanPostProcessor(postProcessor);
}
}
2.将 PostProcessor 添加到 BeanFactory 中的 beanPostProcessors 缓存,见代码块3详解。
代码块3beanFactory.addBeanPostProcessor
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
this.beanPostProcessors.remove(beanPostProcessor);
// 2.将beanPostProcessor添加到beanPostProcessors缓存
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
// 3.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
// 4.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
this.hasDestructionAwareBeanPostProcessors = true;
}
}
该方法作用就是将 BeanPostProcessor 添加到 beanPostProcessors 缓存,这边的先移除再添加,主要是起一个排序的作用。
而 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。
方法总结
- 1.整个 registerBeanPostProcessors 方法围绕 BeanPostProcessor 接口展开, 将 BeanPostProcessor 实现类注册到 BeanFactory 的 beanPostProcessors 缓存中(注意:只注册,不调用,还未到调用时机)
- 2.BeanPostProcessor 实现类具体的 “出场时机” 在创建 bean 实例时,执行初始化方法前后。postProcessBeforeInitialization 方法在执行初始化方法前被调用,postProcessAfterInitialization 方法在执行初始化方法后被调用。
- 3.BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。
📌【7. 初始化消息源】initMessageSource()
方法概述
initMessageSource()方法用来设置国际化资源相关的调用,将实现了MessageSource接口的bean存放在ApplicationContext的成员变量中,先看是否有此配置,如果有就实例化,否则就创建一个DelegatingMessageSource实例的bean
源码剖析
initMessageSource();
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
* 初始化消息源,如果没有默认定义则使用父类的消息源
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果BeanFactory含有messageSource类型的bean,则将bean消息源使用父消息源
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
// 如果已经注册的父上下文没有消息源,则只能将父上下文设置为父消息源
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
// 如果BeanFactory不含有messageSource类型的bean,则使用一个空的消息源来接收getMessage()方法的调用
DelegatingMessageSource dms = new DelegatingMessageSource();
// 其实就是获取到父容器的 messageSource 字段(否则就是 getParent() 上下文自己)
dms.setParentMessageSource(getInternalParentMessageSource());
// 给当前的 messageSource 赋值
this.messageSource = dms;
// 把 messageSource 作为一个单例的 Bean 注册进 beanFactory 工厂里
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
方法总结
初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
- 获取BeanFactory
- 判断容器中是否有id为messageSource的,类型是MessageSource的组件; 如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource; MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
- 将创建完成的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;
【8. 初始化事件广播器】initApplicationEventMulticaster();
方法概述
初始化应用的事件广播器 ApplicationEventMulticaster。
什么是 Spring 事件?
" Spring 通过 ApplicationEvent 类和 ApplicationListener 接口提供 ApplicationContext 中的事件处理。如果将实现 ApplicationListener 接口的 bean 部署到上下文中,则每次将 ApplicationEvent 发布到 ApplicationContext 时,都会通知该 bean。本质上,这是标准的观察者设计模式。
归纳下来主要就是三个部分: 事件、事件发布者、事件监听器。
1.1、Spring中的事件(ApplicationEvent)
spring中的事件有一个抽象父类ApplicationEvent,该类包含有当前ApplicationContext的引用,这样就可以确认每个事件是从哪一个Spring容器中发生的。
1.2、Spring中的事件监听器(ApplicationListener)
spring中的事件监听器同样有一个顶级接口ApplicationListener,只有一个onApplicationEvent(E event)方法,当该监听器所监听的事件发生时,就会执行该方法
1.3、Spring中的事件发布者(ApplicationEventPublisher)
spring中的事件发布者同样有一个顶级接口ApplicationEventPublisher,只有一个方法publishEvent(Object event)方法,调用该方法就可以发生spring中的事件
1.4、Spring中的事件广播器(ApplicationEventMulticaster)
spring中的事件核心控制器叫做事件广播器,接口为ApplicationEventMulticaster,广播器的作用主要有两个:
作用一:将事件监听器注册到广播器中,这样广播器就知道了每个事件监听器分别监听什么事件,且知道了每个事件对应哪些事件监听器在监听
作用二:将事件广播给事件监听器,当有事件发生时,需要通过广播器来广播给所有的事件监听器,因为生产者只需要关心事件的生产,而不需要关心该事件都被哪些监听器消费。
使用监听器
简单来说主要分为以下几个部分:
- 注册事件
- 注册监听器
- 发布事件
在接口调用发布事件时,监听器就会做出相应的操作。
📌源码剖析
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果用户配置了自定义事件广播器,就使用用户的(名称必须是 "applicationEventMulticaster")
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//否则注册一个系统默认的 SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
方法总结
- 如果用户配置了自定义事件广播器,就使用用户的(名称必须是 “applicationEventMulticaster”)
- 否则注册一个系统默认的 SimpleApplicationEventMulticaster
📌【9.刷新:拓展方法】onRefresh()
方法描述
空方法,模板设计模式;子类重写该方法并在容器刷新的时候自定义逻辑;
例:springBoot在onRefresh() 完成内置Tomcat的创建及启动
可以在这里初始化一些特殊的 Bean
源码剖析
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
【10.注册监听器】registerListeners();
方法描述
- 通过addApplicationListener(listen)注册监听器
- 自定义实现ApplicationListen接口的bd
- 发布早期的监听器
源码剖析
protected void registerListeners() {
// Register statically specified listeners first.
// 查出所有通过addApplicationListener方法添加的ApplicationListener(静态指定的),然后注册到事件广播器上
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 查出ioc容器中的所有ApplicationListener,只把他们注册到事件分发器的ApplicationListenerBean上,
// 待使用时再进行实例化
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// 这一步需要注意:如果存在早期应用事件,这里就直接发布了(同时就把 earlyApplicationEvents 字段置为 null)
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
例子:
通过addApplicationListener(listen)注册监听器
其中listen
为实现ApplicationListen接口的bd,且该bd不需要注册进容器
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Test.class);
// 注册监听器
context.addApplicationListener(listen);
// 注册配置类
context.register(Test.class);
// 刷新上下文
context.refresh();
方法总结
注册监听器分为两部分:
- 向事件分发器注册硬编码设置的applicationListener
- 向事件分发器注册一个IOC中的事件监听器(并不实例化)
注意:只是将一些特殊的监听器注册到广播组中,那些在bean配置文件中实现了ApplicationListener接口的类还没有实例化,所以此时只是将name保存到了广播组中,将这些监听器注册到广播组中的操作时在bean的后置处理器中完成的,那时候bean的实例化已经完成了
⭐【11.实例化所有(非惰性初始化)单例Bean】 finishBeanFactoryInitialization(beanFactory)
方法概述
finishBeanFactoryInitialization 是整个 Spring IoC 核心中的核心
。
该方法会实例化所有剩余的非懒加载单例 bean。
除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
源码剖析_finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 1、设置此上下文的类型转换器,不是核心,往下
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.
// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
// 不是核心,继续往下
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 3.初始化LoadTimeWeaverAware Bean实例对象
// 处理 @EnableLoadTimeWeaving 或 <context:load-time-weaver/> 标记的类 不是核心,继续往下
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.
// 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
// 【冻结配置】:设置冻结属性变量为true
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 5.实例化所有剩余(非懒加载)单例对象
beanFactory.preInstantiateSingletons();
}
5.实例化所有剩余(非懒加载)单例对象,见代码块1详解。
MergedBeanDefinition: “合并的 bean 定义”:
之所以称之为 “合并的”,是因为存在 “子定义” 和 “父定义” 的情况。对于一个 bean 定义来说,可能存在以下几种情况:
- 该 BeanDefinition 存在 “父定义”:首先使用 “父定义” 的参数构建一个 RootBeanDefinition,然后再使用该 BeanDefinition 的参数来进行覆盖。
- 该 BeanDefinition 不存在 “父定义”,并且该 BeanDefinition 的类型是 RootBeanDefinition:直接返回该 RootBeanDefinition 的一个克隆。
- 该 BeanDefinition 不存在 “父定义”,但是该 BeanDefinition 的类型不是 RootBeanDefinition:使用该 BeanDefinition 的参数构建一个 RootBeanDefinition。
之所以区分出2和3,是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。
在我们日常使用的过程中,通常会是上面的第3种情况 如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> + @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition。
代码块1:preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.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.
// 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 2.遍历beanNames,触发所有非懒加载单例bean的初始化
for (String beanName : beanNames) {
// 3.获取beanName对应的MergedBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 4.bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 5.判断beanName对应的bean是否为FactoryBean
if (isFactoryBean(beanName)) {
// 5.1 通过beanName获取FactoryBean实例
// 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 5.2 判断这个FactoryBean是否希望急切的初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 5.3 如果希望急切的初始化,则通过beanName获取bean实例
getBean(beanName);
}
} else {
// 6.如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 7.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
for (String beanName : beanNames) {
// 7.1 拿到beanName对应的bean实例
Object singletonInstance = getSingleton(beanName);
// 7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
- 3.获取 beanName 对应的 MergedBeanDefinition,见代码块2详解。
- 5.判断 beanName 对应的 bean 是否为 FactoryBean,见代码块3详解。
- 5.3 和 6. 通过 beanName 获取 bean 实例,finishBeanFactoryInitialization 方法的核心,单独分析!!。
- 7.遍历 beanNames,触发所有 SmartInitializingSingleton 的后初始化回调,这是 Spring 提供的一个扩展点,在所有非懒加载单例实例化结束后调用。
代码块2:getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 1.检查beanName对应的MergedBeanDefinition是否存在于缓存中
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
// 2.如果存在于缓存中则直接返回
return mbd;
}
// 3.如果不存在于缓存中
// 3.1 getBeanDefinition(beanName): 获取beanName对应的BeanDefinition,从beanDefinitionMap缓存中获取
// 3.2 getMergedBeanDefinition: 根据beanName和对应的BeanDefinition,获取MergedBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
代码块3:isFactoryBean
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
// 1.拿到真正的beanName(去掉&前缀、解析别名)
String beanName = transformedBeanName(name);
// 2.尝试从缓存获取Bean实例对象
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
// 3.beanInstance存在,则直接判断类型是否为FactoryBean
return (beanInstance instanceof FactoryBean);
} else if (containsSingleton(beanName)) {
// 4.如果beanInstance为null,并且beanName在单例对象缓存中,则代表beanName对应的单例对象为空对象,返回false
// null instance registered
return false;
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
2.尝试从缓存获取 bean 实例对象,见代码块4详解
代码块4:getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1.从单例对象缓存中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 3.加锁进行操作
synchronized (this.singletonObjects) {
// 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
// 6.从单例工厂缓存中获取beanName的单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
singletonObject = singletonFactory.getObject();
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
// 10.返回单例对象
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
这段代码很重要,在正常情况下,该代码很普通,只是正常的检查下我们要拿的 bean 实例是否存在于缓存中,如果有就返回缓存中的 bean 实例,否则就返回 null。
这段代码之所以重要,是因为该段代码是 Spring 解决循环引用的核心代码。
解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。
另外这个代码块中引进了4个重要缓存:
- singletonObjects 缓存:beanName -> 单例 bean 对象。
- earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
- singletonFactories 缓存:beanName -> ObjectFactory。
【singletonObjects、earlySingletonObjects、singletonFactories 在这边构成了一个类似于 “一、二、三级缓存” 的概念。】
- singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
源码剖析_getBean
@Override
public Object getBean(String name) throws BeansException {
// 获取name对应的bean实例,如果不存在,则创建一个
return doGetBean(name, null, null, false);
}
见 doGetBean 方法详解。
doGetBean
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2.尝试从缓存中获取beanName对应的实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 3.如果beanName的实例存在于缓存中
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 3.1 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 4.scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。
// 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 5.获取parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5.1 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 5.2 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 5.3 尝试在parentBeanFactory中获取bean对象实例
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
markBeanAsCreated(beanName);
}
try {
// 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 7.1 检查MergedBeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 8.1 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 8.3 如果是循环依赖则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 8.4 将dep和beanName的依赖关系注册到缓存中
registerDependentBean(dep, beanName);
// 8.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
getBean(dep);
}
}
// Create bean instance.
// 9.针对不同的scope进行bean的创建
if (mbd.isSingleton()) {
// 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException { //
try {
// 9.1.1 创建Bean实例
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
// 9.1.2 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 9.2 scope为prototype的bean创建
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
// 9.2.2 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
} finally {
// 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
// 9.2.4 返回beanName对应的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 9.3 其他scope的bean创建,可能是request之类的
// 9.3.1 根据scopeName,从缓存拿到scope实例
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 9.3.4 创建bean实例
return createBean(beanName, mbd, args);
} finally {
// 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
}
});
// 9.3.6 返回beanName对应的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 10.检查所需类型是否与实际的bean对象的类型匹配
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
// 10.1 类型不对,则尝试转换bean类型
return getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 11.返回创建出来的bean实例对象
return (T) bean;
}
-
- 尝试从缓存中获取 beanName 对应的实例,见代码块1详解
-
3.1 返回 beanName 对应的实例对象(主要用于 FactoryBean 的特殊处理,普通 bean 会直接返回 sharedInstance 本身),见代码块2详解。
-
9.1 scope 为 singleton 的 bean 创建(新建了一个 ObjectFactory,并且重写了 getObject 方法),见代码块6详解。
-
9.1.1、9.2.2、9.3.4 创建 bean 实例,单独解析!!。
-
9.1.2、9.2.4、9.3.6 返回 beanName 对应的实例对象,见代码块7详解。
-
9.2.1 scope 为 prototype 时创建实例前的操作、9.2.3 scope 为 prototype 时 创建实例后的操作,相对应的两个方法,见代码块5详解。
代码块1:getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1.从单例对象缓存中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 3.加锁进行操作
synchronized (this.singletonObjects) {
// 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
// 6.从单例工厂缓存中获取beanName的单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
singletonObject = singletonFactory.getObject();
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
// 10.返回单例对象
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
这段代码很重要,在正常情况下,该代码很普通,只是正常的检查下我们要拿的 bean 实例是否存在于缓存中,如果有就返回缓存中的 bean 实例,否则就返回 null。
这段代码之所以重要,是因为该段代码是 Spring 解决循环引用的核心代码。
解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。
另外这个代码块中引进了4个重要缓存:
- singletonObjects 缓存:beanName -> 单例 bean 对象。
- earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
- singletonFactories 缓存:beanName -> ObjectFactory。
【singletonObjects、earlySingletonObjects、singletonFactories 在这边构成了一个类似于 “一、二、三级缓存” 的概念。】
- singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
代码块2:getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 1 如果name以“&”为前缀(以“&”为前缀代表想获取的是FactoryBean本身)
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 1.1.如果name以“&”为前缀,但是beanInstance不是FactoryBean,则抛异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
// 1.2 如果beanInstance是FactoryBean,并且name以“&”为前缀,则直接返回beanInstance(以“&”为前缀代表想获取的是FactoryBean本身)
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 2.如果mbd为空,则尝试从factoryBeanObjectCache缓存中获取该FactoryBean创建的对象实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 3.只有beanInstance是FactoryBean才能走到这边,因此直接强转
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
// 4.mbd为空,但是该bean的BeanDefinition在缓存中存在,则获取该bean的MergedBeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
// 5.mbd是否是合成的(这个字段比较复杂,mbd正常情况都不是合成的,也就是false)
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 6.从FactoryBean获取对象实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
// 7.返回对象实例
return object;
}
6.从 FactoryBean 获取对象实例,见代码块2详解。
代码块3:getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 1.如果是单例,并且已经存在于单例对象缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 2.从FactoryBean创建的单例对象的缓存中获取该bean实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 3.调用FactoryBean的getObject方法获取对象实例
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 4.如果该beanName已经在缓存中存在,则将object替换成缓存中的
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (object != null && shouldPostProcess) {
try {
// 5.对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
// 6.将beanName和object放到factoryBeanObjectCache缓存中
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
// 7.返回object对象实例
return (object != NULL_OBJECT ? object : null);
}
} else {
// 8.调用FactoryBean的getObject方法获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
// 9.对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
// 10.返回object对象实例
return object;
}
}
3.调用 FactoryBean 的 getObject 方法获取对象实例,见代码块3详解。
5.对 bean 实例进行后续处理,执行所有已注册的 BeanPostProcessor 的 postProcessAfterInitialization 方法,见代码块4详解。
代码块4:doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
// 1.调用FactoryBean的getObject方法获取bean对象实例
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
// 1.1 带有权限验证的
return factory.getObject();
}
}, acc);
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// 1.2 不带权限
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
// 2.getObject返回的是空值,并且该FactoryBean正在初始化中,则直接抛异常,不接受一个尚未完全初始化的FactoryBean的getObject返回的空值
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
// 3.返回创建好的bean对象实例
return object;
}
很简单的方法,就是直接调用 FactoryBean 的 getObject 方法来获取到对象实例。
细心的同学可以发现,该方法是以 do 开头,通常以 do 开头的方法是最终进行实际操作的方法
例如本方法就是 FactoryBean 最终实际进行创建 bean 对象实例的方法。
代码块5:postProcessObjectFromFactoryBean
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 2.在bean初始化后,调用postProcessAfterInitialization方法
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
// 3.如果返回null,则不会调用后续的BeanPostProcessors
return result;
}
}
return result;
}
在创建完 bean 实例后,会执行 BeanPostProcessor 的 postProcessAfterInitialization 方法。
代码块6:getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
// 1.加锁,避免重复创建单例对象
synchronized (this.singletonObjects) {
// 2.首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 3.beanName对应的bean实例不存在于缓存中,则进行Bean的创建
if (this.singletonsCurrentlyInDestruction) {
// 4.当bean工厂的单例处于destruction状态时,不允许进行单例bean创建,抛出异常
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 5.创建单例前的操作
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// suppressedExceptions用于记录异常相关信息
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
// 6.执行singletonFactory的getObject方法获取bean实例
singletonObject = singletonFactory.getObject();
// 标记为新的单例对象
newSingleton = true;
} catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 7.创建单例后的操作
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 8.如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)
addSingleton(beanName, singletonObject);
}
}
// 9.返回创建出来的单例对象
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
5.创建单例前的操作,7.创建单例后的操作,这两个方法是对应的**,见代码块7详解。**
6.执行 singletonFactory 的 getObject 方法获取 bean 实例,该方法会走 doGetBean 方法的注释 9.1.1。
8.如果是新的单例对象,将 beanName 和对应的单例对象添加到缓存中**,见代码块8详解**
代码块7:beforeSingletonCreation、afterSingletonCreation
protected void beforeSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName加入到正在创建bean的缓存中(Set),如果beanName已经存在于该缓存,会返回false抛出异常(这种情况出现在构造器的循环依赖)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName从正在创建bean的缓存中(Set)移除,如果beanName不存在于该缓存,会返回false抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
inCreationCheckExclusions 是要在创建检查排除掉的 beanName 集合,正常为空,可以不管。这边主要是引入了 singletonsCurrentlyInCreation 缓存:当前正在创建的 bean 的 beanName 集合。在 beforeSingletonCreation 方法中,通过添加 beanName 到该缓存,可以预防出现构造器循环依赖的情况。
为什么无法解决构造器循环依赖?
- 在finishBeanFactoryInitialization详解 中的代码块7提过,getSingleton 方法是解决循环引用的核心代码。
- 解决逻辑的第一句话:“我们先用构造函数创建一个 “不完整” 的 bean 实例”,从这句话可以看出,构造器循环依赖是无法解决的,因为当构造器出现循环依赖,我们连 “不完整” 的 bean 实例都构建不出来。
- Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖。
代码块8:addSingleton
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 1.添加到单例对象缓存
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
// 2.将单例工厂缓存移除(已经不需要)
this.singletonFactories.remove(beanName);
// 3.将早期单例对象缓存移除(已经不需要)
this.earlySingletonObjects.remove(beanName);
// 4.添加到已经注册的单例对象缓存
this.registeredSingletons.add(beanName);
}
}
源码剖析_createBean
【实例化】createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 1.解析beanName对应的Bean的类型,例如:com.demo.open.demo.service.impl.UserServiceImpl
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
// 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
// 该拷贝副本取代mdb用于后续的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2.验证及准备覆盖的方法(对override属性进行标记及验证)
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 5.创建Bean实例(真正创建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
// 6.返回创建的Bean实例
return beanInstance;
}
5.创建 bean 实例,见代码块1详解
代码块1:doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 1.新建Bean包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4.拿到创建好的Bean实例
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// 5.拿到Bean实例的类型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
// Autowired注解正是通过此方法实现注入类型的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 8.提前曝光beanName的ObjectFactory,用于解决循环引用
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance. 初始化bean实例。
Object exposedObject = bean;
try {
// 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 10.对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);
}
}
if (earlySingletonExposure) {
// 11.如果允许提前曝光实例,则进行循环依赖检查
Object earlySingletonReference = getSingleton(beanName, false);
// 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
// && 当前bean有被其他bean依赖
// 11.4 拿到依赖当前bean的所有bean的beanName数组
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 11.6 移除失败的添加到 actualDependentBeans
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 13.完成创建并返回
return exposedObject;
}
3.根据 beanName、mbd、args,使用对应的策略创建 bean 实例,并返回包装类 BeanWrapper,见代码块2详解。
代码块2:createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析bean的类型信息
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
// beanClass不为空 && beanClass不是公开类(不是public修饰) && 该bean不允许访问非公共构造函数和方法,则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 1.如果存在工厂方法则使用工厂方法实例化bean对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// resolved: 构造函数或工厂方法是否已经解析过
boolean resolved = false;
// autowireNecessary: 是否需要自动注入(即是否需要解析构造函数参数)
boolean autowireNecessary = false;
if (args == null) {
// 2.加锁
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 2.1 如果resolvedConstructorOrFactoryMethod缓存不为空,则将resolved标记为已解析
resolved = true;
// 2.2 根据constructorArgumentsResolved判断是否需要自动注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 3.如果已经解析过,则使用resolvedConstructorOrFactoryMethod缓存里解析好的构造函数方法
if (autowireNecessary) {
// 3.1 需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 3.2 否则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
// 4.应用后置处理器SmartInstantiationAwareBeanPostProcessor,拿到bean的候选构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 5.如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 6.没有特殊处理,则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
instantiateBean(beanName, mbd);
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
// 是不是有java安全管理之类的设置,没有,跳过
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 实例化( 进入),ctor.newInstance!
// 对象诞生在这里!!!
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 包装一下,返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
单例对象实例化完成,回到doCreateBean()方法,对象实例化完成后要存入三级缓存(为了后面解决循环依赖):详见代码块3
代码块3:addSingletonFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 1.如果beanName不存在于singletonObjects缓存
if (!this.singletonObjects.containsKey(beanName)) {
// 2.将beanName和singletonFactory注册到singletonFactories缓存(三级缓存)(beanName -> 该beanName的单例工厂)
this.singletonFactories.put(beanName, singletonFactory);
// 3.移除earlySingletonObjects缓存中的beanName(beanName -> beanName的早期单例对象)
this.earlySingletonObjects.remove(beanName);
// 4.将beanName注册到registeredSingletons缓存(已经注册的单例集合)
this.registeredSingletons.add(beanName);
}
}
}
【属性注入】populateBean
populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1.返回此bean的属性值
PropertyValues pvs = mbd.getPropertyValues();
// 2.bw为空时的处理
if (bw == null) {
if (!pvs.isEmpty()) {
// 2.1 如果bw为空,属性不为空,抛异常,无法将属性值应用于null实例
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// Skip property population phase for null instance.
// 2.2 如果bw为空,属性也为空,则跳过
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 用于标识是否继续之后的属性填充
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 3.1 如果mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor,则遍历处理InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 3.2 在bean实例化后,属性填充之前被调用,允许修改bean的属性,如果返回false,则跳过之后的属性填充
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 3.3 如果返回false,将continueWithPropertyPopulation赋值为false,代表要跳过之后的属性填充
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 3.4 如果continueWithPropertyPopulation为false,则跳过之后的属性填充
if (!continueWithPropertyPopulation) {
return;
}
// 4.解析自动装配模式为AUTOWIRE_BY_NAME和AUTOWIRE_BY_TYPE(现在几乎不用)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
// 4.1 解析autowireByName的注入
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 4.2 解析autowireByType的注入
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 5.BeanFactory是否注册过InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 6.是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
// 7.注册过InstantiationAwareBeanPostProcessors 或者 需要依赖检查
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
// 7.1 应用后置处理器InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 7.1.1 应用后置处理器InstantiationAwareBeanPostProcessor的方法postProcessPropertyValues,
// 进行属性填充前的再次处理。例子:现在最常用的@Autowire属性注入就是这边注入依赖的bean实例对象
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 7.2 依赖检查,对应depends-on属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 8.将所有PropertyValues中的属性填充到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
populateBean(...)
是根据BeanDefinition将属性赋值到刚创建的对象中,主要的逻辑在applyPropertyValues(...)
中执行,详见代码1
代码1:applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 若没有要注入的属性,直接返回
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
// 1.获取属性值列表
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 1.1 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到BeanWrapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
// 1.2 如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
// 显然,若调用者没有自定义转换器,那就使用BeanWrapper本身~~~(因为BeanWrapper实现了TypeConverter 接口~~)
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 2.1 创建属性解析器(主要完成属性值的处理,包括依赖其他bean的创建)
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
// 2.2 创建深层拷贝副本,用于存放解析后的属性值
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 3.遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
// 3.1 如果pv已经包含转换的值,则直接添加到deepCopy
deepCopy.add(pv);
}
else {
// 3.2 否则,进行转换
// 3.2.1 获取属性名称
String propertyName = pv.getName();
// 3.2.2 使用解析器解析不同类型的值
Object originalValue = pv.getValue();
// AutowiredPropertyMarker.INSTANCE 自动生成标记的规范实例(不进入)
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
/*
* 【重点】使用解析器解析不同类型的值(包括循环依赖的解决)
*/
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
// 将值包装到deepCopy的list中
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
// 属性类型转换器,如果有定义的类型转换,就发生在这里 convertForProperty
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 最后通过反射setXXXX()来设置属性值!!!【关键点】
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
主要逻辑是如下:
- 创建属性解析器valueResolver, 之后循环BeanDefinition中的属性列表,使用解析器对每个property进行实际值的解析(保存创建依赖bean对象)
- 根据属性的名称将属性值赋值到对象中
4.涉及到循环依赖的逻辑是valueResolver.resolveValueIfNecessary(pv, originalValue)
,使用属性解析器获取property的实际内容,下面我们看下如何解析property的(只看依赖其他bean的property):详见代码块2
代码块2:resolveValueIfNecessary
//org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
//处理依赖其他bean的property
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
//省略...
}
//详细处理逻辑
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
//获取依赖bean名称
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
//依赖是否属于父容器
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
//嵌套调用IOC容器的getBean方法
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
上述逻辑比较清晰简单,就是根据依赖的beanName嵌套调用this.beanFactory.getBean(refName)
去创建所依赖对象,创建完成后返回该bean信息。
【初始化】initializeBean
initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 1.激活Aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2.在初始化前应用BeanPostProcessor的postProcessBeforeInitialization方法,允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3.调用初始化方法
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()) {
// 4.在初始化后应用BeanPostProcessor的postProcessAfterInitialization方法,允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
// 5.返回wrappedBean
return wrappedBean;
}
1.激活 Aware方法,见代码块1详解。
2.在初始化前应用后置处理器 BeanPostProcessor 的 postProcessBeforeInitialization 方法,允许对 bean 实例进行包装,见代码块2详解。
3.调用初始化方法,见代码块3详解。
4.在初始化后应用后置处理器 BeanPostProcessor 的 postProcessAfterInitialization 方法,允许对 bean 实例进行包装,见代码块5详解。
代码块1:invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
// BeanNameAware: 实现此接口的类想要拿到beanName,因此我们在这边赋值给它
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoaderAware:实现此接口的类想要拿到beanClassLoader,因此我们在这边赋值给它
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
// BeanFactoryAware: 实现此接口的类想要拿到 BeanFactory,因此我们在这边赋值给它
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
如果对 Spring 比较熟悉的同学应该知道,以 Aware 为结尾的类都是一些扩展接口,用于提供给开发者获取到 BeanFactory 中的一些属性或对象。
代码块2:applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessBeforeInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 2.在bean初始化方法执行前,调用postProcessBeforeInitialization方法
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
在 bean 初始化前,调用所有 BeanPostProcessors 的 postProcessBeforeInitialization 方法
代码块3:invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
// 1.首先检查bean是否实现了InitializingBean接口,如果是的话调用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
// 2.调用afterPropertiesSet方法
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 3.调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
2.调用自定义初始化方法,见代码块4详解。
代码块4:invokeCustomInitMethod
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
// 1.拿到初始化方法的方法名
String initMethodName = mbd.getInitMethodName();
// 2.根据方法名拿到方法
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
// 3.如果不存在initMethodName对应的方法,并且是强制执行初始化方法(默认为强制), 则抛出异常
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
} else { // 如果设置了非强制,找不到则直接返回
if (logger.isDebugEnabled()) {
logger.debug("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
// 4.调用初始化方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
ReflectionUtils.makeAccessible(initMethod);
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
initMethod.invoke(bean);
return null;
}
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
} else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
代码块5:applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 2.在bean初始化方法执行后,调用postProcessAfterInitialization方法
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
【注册销毁方法】registerDisposableBeanIfNecessary
销毁方法有三种:
public class DestroyMethodBean implements DisposableBean {
//jdk的注解
@PreDestroy
public void preDestroy(){
System.out.println("======@PreDestroy======");
}
@Override
public void destroy(){
System.out.println("======DisposableBean.destroy()======");
}
//基于配置
public void destroyMethod(){
System.out.println("======<destroy-method>======");
}
}
registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 1.mbd的scope不是prototype && 给定的bean需要在关闭时销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// 2.单例模式下注册用于销毁的bean到disposableBeans缓存,执行给定bean的所有销毁工作:
// DestructionAwareBeanPostProcessors,DisposableBean接口,自定义销毁方法
// 2.1 DisposableBeanAdapter:使用DisposableBeanAdapter来封装用于销毁的bean
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
} else {
// 3.自定义scope处理
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
1.requiresDestruction(bean, mbd):判断给定的 bean 是否需要在关闭时销毁,见代码块1详解。
2.1 使用 DisposableBeanAdapter 来封装用于销毁的 bean,见代码块2详解。
要注册销毁方法,Bean需要至少满足以下三个条件之一:
(1)Bean是DisposableBean的实现类,此时执行DisposableBean的接口方法destroy()
(2)Bean标签中有配置destroy-method属性,此时执行destroy-method配置指定的方法
(3)当前Bean对应的BeanFactory中持有DestructionAwareBeanPostProcessor接口的实现类,此时执行DestructionAwareBeanPostProcessor的接口方法postProcessBeforeDestruction
在满足上面三个条件之一的情况下,容器便会注册销毁该Bean,注册Bean的方法很简单,见registerDisposableBean方法实现:见代码3详解
代码块1:requiresDestruction
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
// 1.DisposableBeanAdapter.hasDestroyMethod(bean, mbd):判断bean是否有destroy方法
// 2.hasDestructionAwareBeanPostProcessors():判断当前BeanFactory是否注册过DestructionAwareBeanPostProcessor
// 3.DisposableBeanAdapter.hasApplicableProcessors:是否存在适用于bean的DestructionAwareBeanPostProcessor
return (bean != null &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
1.DisposableBeanAdapter.hasDestroyMethod(bean, mbd):判断 bean 是否有 destroy 方法,见代码块20详解。
3.DisposableBeanAdapter.hasApplicableProcessors:是否存在适用于 bean 的 DestructionAwareBeanPostProcessor,见代码块21详解。
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
if (bean instanceof DisposableBean || closeableInterface.isInstance(bean)) {
// 1.如果bean实现了DisposableBean接口 或者 bean是AutoCloseable实例,则返回true
return true;
}
// 2.拿到bean自定义的destroy方法名
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
// 3.如果自定义的destroy方法名为“(inferred)”(该名字代表需要我们自己去推测destroy的方法名),
// 则检查该bean是否存在方法名为“close”或“shutdown”的方法,如果存在,则返回true
return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
}
// 4.如果destroyMethodName不为空,则返回true
return StringUtils.hasLength(destroyMethodName);
}
1.如果 bean 实现了 DisposableBean 接口或 bean 是 AutoCloseable 实例,则返回 true,因为这两个接口都有关闭的方法。
代码块2:DisposableBeanAdapter
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
//实现了DisposableBean && 没有叫destroy的被@PreDestroy注解的方法
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
//<destroy-method>设置的值
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
//<destroy-method> 有值 && (没有既实现DisposableBean,<destroy-method>值又叫destroy) && 被@PreDestroy注解的方法不叫<destroy-method>值
//其实就是三种方法的名字互相不能相同
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
this.destroyMethod = determineDestroyMethod(destroyMethodName);
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
}
//可以过滤出InitDestroyAnnotationBeanPostProcessor
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
##### 代码块3:registerDisposableBean
```java
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
容器销毁的时候,会遍历disposableBeans,逐一执行销毁方法。
关闭容器时:会调用DisposableBeanAdapter的destroy()方法
public void destroy() {
// 执行@PreDestroy方法
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// bean实现了 DisposableBean 接口而且前面通过后置处理器找到的destroyName不是 "destroy"
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
// 在构造函数中 得到的 destroyName
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
方法总结
在 finishBeanFactoryInitialization 方法中,我们主要做了以下操作:
- 将之前解析的 BeanDefinition 进一步处理,将有父 BeanDefinition 的进行合并,获得 MergedBeanDefinition
- 尝试从缓存获取 bean 实例
- 处理特殊的 bean —— FactoryBean 的创建
- 创建 bean 实例
- 循环引用的处理
- bean 实例属性填充
- bean 实例的初始化
- BeanPostProcessor 的各种扩展应用
finishBeanFactoryInitialization 方法解析的结束,也标志着 Spring IoC 整个构建过程中,重要的内容基本都已经解析完毕
【12. 结束refresh操作】finishRefresh();
方法概述
完成此上下文的刷新,主要是推送上下文刷新完毕事件(ContextRefreshedEvent )到监听器
源码剖析
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//清除resourceCaches资源缓存中的数据
clearResourceCaches();
// Initialize lifecycle processor for this context.
//注释1. 为此上下文初始化生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//注释2. 首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
getLifecycleProcessor().onRefresh();
// Publish the final event.
//注释3. 推送上下文刷新完毕事件到相应的监听器
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
8. Bean-循环依赖
什么是循环依赖?
循环依赖:一个或多个对象实例之间存在直接或间接的依赖关系,这种依赖关系构成了构成一个环形调用(闭环)。
例:第一种情况:两个对象之间的直接依赖:
第二种情况:多个对象之间的间接依赖
注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
怎么检测是否存在循环依赖
检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标记,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。
循环依赖_效果演示
Spring中循环依赖场景有:
- 构造器的循环依赖
- field属性的循环依赖
(1)构造器的循环依赖
构造器的循环依赖就是在构造器中有属性循环依赖,如下:
public class testService1 {
private testService2 service_2;
public testService1(testService2 service_2) {
this.service_2 = service_2;
}
public void aTest(){
System.out.println("testService1,注入了属性" + service_2 );
}
}
public class testService2 {
private testService1 service_1;
public testService2(testService1 service_1) {
this.service_1 = service_1;
}
public void bTest(){
System.out.println("testService2,注入了属性" + service_1 );
}
}
applicationContext.xml
<!--testService1通过构造方法注入testService2-->
<bean id="testService1" class="com.demo.cyclic.testService1">
<constructor-arg name="service_2" ref="testService2"/>
</bean>
<!--testService2通过构造方法注入testService1-->
<bean id="testService2" class="com.demo.cyclic.testService2">
<constructor-arg name="service_1" ref="testService1"/>
</bean>
测试代码:
/**
* 循环依赖效果演示
* @param args
*/
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:applicationContext-cyclic.xml");
testService1 testService1 = (com.demo.cyclic.testService1) applicationContext.getBean("testService1");
testService1.aTest();
}
测试结果:产生了循环依赖
(2)field属性的循环依赖
public class TestService1 {
private TestService2 testService2;
public void setTestService2(TestService2 testService2) {
this.testService2 = testService2;
}
public void aTest(){
System.out.println("testService1,注入了" + testService2 );
}
}
public class TestService2 {
private TestService1 testService1;
public void setTestService1(TestService1 testService1) {
this.testService1 = testService1;
}
public void aTest(){
System.out.println("testService1,注入了属性" + testService1 );
}
}
applicationContext.xml
<bean id="testService1" class="com.demo.cyclic.TestService1">
<property name="testService2" ref="testService2"/>
</bean>
<bean id="testService2" class="com.demo.cyclic.TestService2">
<property name="testService1" ref="testService1" />
</bean>
测试结果:
结论:
构造器注入引起的循环依赖(不能解决)
单例Bean的Setter注入产生的循环依赖(能解决)
Spring怎么解决循环依赖
Spring的循环依赖的理论依据其实是基于Java的引用传递,当我们获取到对象的引用时,对象的field或则属性是可以延后设置的(但是构造器必须是在获取引用之前)。
⭐三级缓存
Spring为了解决单例的循环依赖问题,使用了三级缓存(三个map)
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
⭐Spring解决循环依赖流程图
循环依赖_源码剖析
1.使用getBean(java.lang.Class)从IOC中获取bean信息,实际上在IOC容器通过扫描包或加载XML后也会循环调用getBean(…)进行Bean的首轮实例化。
下面来详细了解下getBean(…)中对于循环依赖的处理:
//org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
//doGetBean是getBean方法的实际逻辑方法,这里只贴出了相关的部分代码
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//处理bean名称的规范问题
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//从缓存中获取bean实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//省略...
try {
//获取beanName对应的BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//省略...
// Create bean instance.
//根据bean的作用域来创建bean实例
if (mbd.isSingleton()) {
//创建单例模式的bean
sharedInstance = getSingleton(beanName, () -> {
try {
//单例的bean实例化方法
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//创建原型模式bean
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}else {
//创建其他模式bean
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//省略...
return (T) bean;
}
上述doGetBean大致做了几个步骤:
-
1.尝试根据beanName从缓存中获取获取bean对象
-
2.若获取到缓存对象则执行getObjectForBeanInstance(…)后返回bean信息
-
3.若没有获取到缓存对象(首次创建),则根据bean的作用域类型来采取不同方式创建bean(这里默认为单例模式),然后再执行getObjectForBeanInstance(…)后返回bean信息
其中涉及到循环依赖的处理有getSingleton(beanName)先获取缓存对象:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 1.从单例对象缓存(1级缓存)中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2.如果单例对象缓存(1级缓存)中没有,并且该beanName对应的单例bean正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 3.从早期单例对象缓存中(二级缓存)获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 4.如果在早期单例对象缓存中(二级缓存)也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
// 6.从单例工厂缓存中(三级缓存)获取beanName的单例工厂
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 再次从二级缓存中获取,重复校验
singletonObject = this.earlySingletonObjects.get(beanName);
// 为null
if (singletonObject == null) {
// 6.再从单例工厂缓存中(三级缓存)获取beanName的单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
singletonObject = singletonFactory.getObject();
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
分别从一级缓存、二级缓存、三级缓存中进行查找
2.这里我们的bean按照单例模式,走首次创建路径createBean(beanName, mbd, args);,而createBean(beanName, mbd, args);中真正的逻辑方法是doCreateBean(…),下面我们看下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()) {
//根据beanName将当前对象从未完成实例化列表缓存中移除并返回
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//若未完成实例化列表缓存中没有数据则创建一个空对象
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
//省略...
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//将bean写入提前暴露的缓存中(此时的bean刚实例化,还没有对其属性进行赋值处理)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//将beandefinition中的属性写入对应的instanceWrapper对象实例中
//依赖循环就是在这里处理的
populateBean(beanName, mbd, instanceWrapper);
//如果exposedObject对象有实现一些aware、init接口则初始化这些接口
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);
}
}
//省略...
return exposedObject;
}
doCreateBean(…)的主要逻辑有以下几步:
- 创建一个bean的包装对象instanceWrapper(实际为Class.forName(className).newInstance()创建,有兴趣自行可跟踪代码)
- 通过addSingletonFactory(…)将刚实例化的对象放入缓存中
- 在populateBean(…)中处理bean对象的依赖属性(在这里递归调用其他依赖的bean)
- 在initializeBean(…)中调用对象的一些初始化接口(如实现InitializingBean),并返回结果bean
涉及循环依赖的处理有addSingletonFactory(…)和populateBean(…)两部分,我们先看下addSingletonFactory(…)将bean加入缓存中:
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
//没有创建过beanName的bean则加入缓存
if (!this.singletonObjects.containsKey(beanName)) {
//存储在singletonFactories中,在getSingleton(...)中获取调用
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
//参数ObjectFactory<?> singletonFactory是一个函数式接口对象
//内容为() -> getEarlyBeanReference(beanName, mbd, bean)
//调用singletonFactory会执行getEarlyBeanReference(beanName, mbd, bean),返回bean的首次创建对象
//实际上会在获取缓存对象的getSingleton(...)中调用 singletonFactory.getObject();
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
//忽略...
return exposedObject;
}
3.而populateBean(...)
是根据BeanDefinition将属性赋值到刚创建的对象中,主要的逻辑在applyPropertyValues(...)
中执行,大致代码如下:
//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//省略...
//创建属性解析器(主要完成属性值的处理,包括依赖其他bean的创建)
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
//获取属性名称
String propertyName = pv.getName();
Object originalValue = pv.getValue();
//使用解析器解析不同类型的值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//将值包装到deepCopy的list中
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
//将属性赋值到对象中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
主要逻辑是如下:
- 创建属性解析器valueResolver, 之后循环BeanDefinition中的属性列表,使用解析器对每个property进行实际值的解析(保存创建依赖bean对象)
- 根据属性的名称将属性值赋值到对象中
4.涉及到循环依赖的逻辑是valueResolver.resolveValueIfNecessary(pv, originalValue),使用属性解析器获取property的实际内容,下面我们看下如何解析property的(只看依赖其他bean的property):
//org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
//处理依赖其他bean的property
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
//省略...
}
//详细处理逻辑
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
//获取依赖bean名称
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
//依赖是否属于父容器
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
//嵌套调用IOC容器的getBean方法
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
上述逻辑比较清晰简单,就是根据依赖的beanName嵌套调用this.beanFactory.getBean(refName)
去创建所依赖对象,创建完成后返回该bean信息。
总结: 到这里我们就可以知道spring是如何处理依赖循环的了:
(1)调用getBean(…)方法创建一个bean,前先从缓存getSingleton(…)中获取对象信息
(2)若是没有缓存,则首次创建后将其对象加入到三级缓存中
(3)之后对创建的对象进行属性填充populateBean(…),填充过程中创建属性解析器对bean的属性进行处理
(4)若属性类型依赖其他的bean,则会嵌套调用IOC容器的getBean方法去创建所依赖的bean对象,直到出现从缓存中获取到对象后跳出嵌套逻辑,才可以完成整个bean的属性赋值过程。
循环依赖经典面试题
【Spring 为何需要三级缓存解决循环依赖,而不是二级缓存?】
答:只要两个缓存确实可以做到解决循环依赖的问题,但是有一个前提这个bean没被AOP进行切面代理,如果这个bean被AOP进行了切面代理,那么只使用两个缓存是无法解决问题
【三级缓存中为什么要添加ObjectFactory
对象,而不是直接保存实例对象?】
答:因为假如想对添加到三级缓存中的实例对象进行增强,直接用实例对象是行不通的。
【构造器注入注入的循环依赖为什么无法解决?】
答:源码中对于解决逻辑的第一句话:“我们先用构造函数创建一个 “不完整” 的 bean 实例”,从这句话可以看出,构造器循环依赖是无法解决的,因为当构造器出现循环依赖,我们连 “不完整” 的 bean 实例都构建不出来。