目录
- 1. Spring整体设计架构
- 2. Spring IOC容器初始化流程
- 2.1. SpringApplication.run(Application.class, args),实际调用new SpringApplication(null, primarySources).run(args)。
- 2.2 refreshContext(ConfigurableApplicationContext context)方法实现如下,实际上是调用的传入的IOC容器的refresh()方法。
- 2.3 finishBeanFactoryInitialization(beanFactory)
- 2.4 getBean(String name)
- 2.5 doGetBean方法
- 2.6 getSingleton方法
- 2.7 createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法
- 2.8 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
1. Spring整体设计架构
1.1 BeanRegistry系列接口及BeanFactory接口关系
- BeanFactory接口: 工厂模式定义了IOC容器的基本功能规范
- BeanRegistry系列接口: 向IOC容器手工注册 BeanDefinition 对象的方法
1.1.1 BeanFactory接口
BeanFactory接口实现如下:
public interface BeanFactory {
//用于取消引用实例并将其与FactoryBean创建的bean区分开来。例如,如果命名的bean是FactoryBean,则获取将返回Factory,而不是Factory返回的实例。
String FACTORY_BEAN_PREFIX = "&";
//根据bean的名字和Class类型等来得到bean实例
Object getBean(String name) throws BeansException;
Object getBean(String name, Class requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
//返回指定bean的Provider
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
//检查工厂中是否包含给定name的bean,或者外部注册的bean
boolean containsBean(String name);
//检查所给定name的bean是否为单例/原型
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
//判断所给name的类型与type是否匹配
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//获取给定name的bean的类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//返回给定name的bean的别名
String[] getAliases(String name);
}
BeanFactory有三个子类接口,ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。
- ListableBeanFactory接口:该接口定义了访问容器中 Bean 基本信息的若干方法,如查看Bean 的个数、获取某一类型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
- HierarchicalBeanFactory接口:父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器; 通过 HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean。Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean。
- AutowireCapableBeanFactory接口:定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
还有其他BeanFactory接口或者抽象类,均是此三个接口子类。
- ConfigurableBeanFactory接口:继承自ConfigurableBeanFactory接口和SingletonBeanRegistry接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法;
- ConfigurableListableBeanFactory接口:继承自ListableBeanFactory接口/AutowireCapableBeanFactory接口和ConfigurableBeanFactory接口,等于是继承了BeanFactory的全部三个子类接口及SingletonBeanRegistry接口。
1.1.2 BeanRegistry系列接口
最核心的接口有两个:
- BeanDefinitionRegistry接口,实现类DefaultListableBeanFactory;
- SingletonBeanRegistry接口,实现类DefaultSingletonBeanRegistry;
1.1.2.1 BeanDefinitionRegistry接口及DefaultListableBeanFactory实现类
BeanDefinitionRegistry接口定义了关于 BeanDefinition 的注册、移除、查询等一系列的操作。
public interface SingletonBeanRegistry {
// 注册单例 Bean。其实就是将该 Bean 保存到一个专门存储单例 Bean 实例的Map中,Key是 beanName,Value是对应的单例 Bean 实例
void registerSingleton(String beanName, Object singletonObject);
// 通过 beanName 获取该单例 Bean 实例
Object getSingleton(String beanName);
// 通过 beanName 判断该单例 Bean 实例是否存在
boolean containsSingleton(String beanName);
// 返回所有单例 Bean 的名称
String[] getSingletonNames();
// 返回已注册的单例 Bean 实例数量
int getSingletonCount();
// 返回当前使用的单例锁,主要提供给外部协作者使用
Object getSingletonMutex();
}
该接口有三个实现类:DefaultListableBeanFactory、GenericApplicationContext、SimpleBeanDefinitionRegistry,其中 GenericApplicationContext 底层调用的是 DefaultListableBeanFactory 中的实现方法。故,DefaultListableBeanFactory类是BeanDefinitionRegistry接口核心实现类。
核心代码如下:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
...
// 存储所有的 BeanDefinition ,key 是 Bean 的名称。我们一直称呼的容器,底层就是这个 Map
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 存储所有 Bean 名称
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
// 存储手动注册的单例 Bean 名称
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
// 存储冻结的 BeanDefinition,留作后面缓存用
private volatile String[] frozenBeanDefinitionNames;
...
// 方法的入参为 Bean 名称和对应的 BeanDefinition
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
// 如果 beanDefinition 的实例为 AbstractBeanDefinition,则进行验证
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// 验证:
// 如果有重写方法,但是是工厂方法,则抛出异常,因为重写方法需要代理,而工厂方法无法代理;
// 通过方法名称,判断 Bean 中该名称方法存在的数量,0:方法不存在,报错;1:方法非重载,overloaded 属性设为 false;
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
// 先从 beanDefinitionMap 中尝试获取 beanName 对应 BeanDefinition
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
// 不为 null,则 beanName 对应的 BeanDefinition 已经存在
if (oldBeanDefinition != null) {
// 是否应允许覆盖 BeanDefinition,不允许则抛异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
/***************************** 若允许覆盖 *****************************/
// 判断 Bean 的角色大小:
// 0:用户定义的 Bean、1:来源于配置文件的 Bean、2:Spring 内部的 Bean;
// 当原 BeanDefinition 角色小于新的 BeanDefinition 角色时,输出一个 warn 日志,提示 BeanDefinition 被覆盖
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 + "]");
}
}
// 当新 BeanDefinition 属性值不等于原 BeanDefinition 属性值时,输出 info 提示信息
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 + "]");
}
}
// 最后,输出 debug 日志信息:用等效的新 BeanDefinition 覆盖原 BeanDefinition
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
// 添加至 BeanDefinition 集合,并覆盖原 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
// Map 中无对应的 BeanDefinition,则直接注册
else {
// 已开始创建 Bean
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
// 将 Bean 对应的 BeanDefinition 放入 beanDefinitionMap 中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 创建新的 beanNames 集合,并将已缓存的 beanName 和新的 beanName 加入该集合
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 在手动注册 Bean 的集合中,如果存在同名的 beanName,则将集合中同名的 beanName 删除
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
// 仍处于启动注册阶段
else {
// 将当前 Bean 对应的 BeanDefinition 放入 beanDefinitionMap 中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将当前 beanName 放入 beanDefinitionNames
this.beanDefinitionNames.add(beanName);
// 删除手动注册 Bean 集合中同名的 beanName
this.manualSingletonNames.remove(beanName);
}
// 将存储冻结 BeanDefinition 的 Map 置为 null
this.frozenBeanDefinitionNames = null;
}
// 当前注册的 BeanDefinition 已在 beanDefinitionMap 中存在,或者其实例已在存储单例 Bean 的 Map 中存在
if (oldBeanDefinition != null || containsSingleton(beanName)) {
// 重置 BeanDefinition,主要做一些清理工作
resetBeanDefinition(beanName);
}
}
}
执行完 registerBeanDefinition 方法后,Bean 的名称和对应的 BeanDefinition 就被放入了容器中,后续获取 Bean 也是从这个容器中获取。
当然,DefaultListableBeanFactory 还实现了 BeanDefinitionRegistry 接口的其它方法,如对 BeanDefinition 进行移除、判断是否存在、获取数量等操作,其实都是围绕 beanDefinitionMap 这个 Map 进行的,这里就不详细介绍。
1.1.2.2 SingletonBeanRegistry接口及DefaultSingletonBeanRegistry实现类
SingletonBeanRegistry接口统一操作单例 Bean 实例,通过该接口可直接对单例 Bean 的实例进行存储、注册等操作。这个接口其实和BeanDefinitionRegistry接口功能类似,但是其DefaultSingletonBeanRegistry实现类的扩展却解决了单例Bean间的循环依赖问题。
public interface SingletonBeanRegistry {
// 注册单例 Bean。其实就是将该 Bean 保存到一个专门存储单例 Bean 实例的Map中,Key是 beanName,Value是对应的单例 Bean 实例
void registerSingleton(String beanName, Object singletonObject);
// 通过 beanName 获取该单例 Bean 实例
Object getSingleton(String beanName);
// 通过 beanName 判断该单例 Bean 实例是否存在
boolean containsSingleton(String beanName);
// 返回所有单例 Bean 的名称
String[] getSingletonNames();
// 返回已注册的单例 Bean 实例数量
int getSingletonCount();
// 返回当前使用的单例锁,主要提供给外部协作者使用
Object getSingletonMutex();
}
DefaultSingletonBeanRegistry实现类核心代码如下,可以看到不仅用了三层缓存来解决Bean的循环依赖问题,还用其他缓存记录了Bean之间的关系及处于创建/销毁状态的Bean等。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/********** 1、定义的一些 Map 属性,用来保存单例 Bean 实例、 Bean 的依赖关系 **********/
// 缓存单例 Bean 实例,Key 是 beanName,Value 是单例 Bean 实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 缓存 Bean 对应的 ObjectFactory
// ObjectFactory 是获取 Bean 实例的工厂,只不过这里获取的 Bean 还未完全实例化,属于提早暴露的 Bean
// 该属性在解决循环依赖时使用,后续会深入讨论
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 缓存 singletonFactories 属性中通过 ObjectFactory 创建的 Bean
// 该属性也是在解决循环依赖时使用,后续会深入讨论
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 保存已注册的单例 Bean 名称
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
// 保存当前正在创建的 Bean 的名称
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 保存当前从创建检查中排除的 Bean 的名称
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
...
// 当前 Bean 是否处于销毁状态
private boolean singletonsCurrentlyInDestruction = false;
// 保存实现了 DisposableBean 接口的 Bean,在销毁 Bean 时,会回调该 Bean 中的 destory 方法
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
// 保存 Bean 的包含关系,key 是 Bean 的名称,value 是 Bean 里面包含的其它 Bean 名称集合
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
// 保存 Bean 的依赖关系:key 是 Bean 的名称,value 是依赖于该 Bean 的其它 Bean 名称集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
// 保存 Bean 的依赖关系:key 是 Bean 的名称,value 是该 Bean 所依赖的其它 Bean 名称集合
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/******************************** 2、注册单例 Bean 实例及对应的实例工厂 ********************************/
// 注册单例 Bean 实例
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
// 通过 beanName 获取 Map 中对应的单例 Bean 实例
Object oldObject = this.singletonObjects.get(beanName);
// 如果不为空,则抛出异常,因为单例已经存在,无法再次注册
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
// 为空,则进入 addSingleton 方法
addSingleton(beanName, singletonObject);
}
}
// 缓存单例 Bean 实例
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 将单例 Bean 实例存放至 singletonObjects 集合
this.singletonObjects.put(beanName, singletonObject);
// 当 beanName 对应的 Bean 实例已被存放至 singletonObjects 集合时,singletonFactories
// 和 earlySingletonObjects 集合则不能再持有 beanName 对应的 ObjectFactory 和实例
// 其中原因会在后续循环依赖的文章深入讨论
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 存储 Bean 名称
this.registeredSingletons.add(beanName);
}
}
// 缓存 Bean 对应的 ObjectFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
/********************************* 3、获取单例 Bean 实例 *********************************/
@Override
public Object getSingleton(String beanName) {
// 该方法较为复杂,在后续结合循环依赖的场景讨论
}
...
/***************************** 4、对单例 Bean 实例的基础操作 *****************************/
// 删除单例 Bean 实例
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
// 判断 beanName 对应的单例 Bean 实例时候存在
@Override
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
}
// 返回所有单例 Bean 的 beanName
@Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
// 返回单例 Bean 实例数量
@Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
...
/*************************************** 5、 Bean 的状态 **************************************/
// beanName 对应的 Bean 是否处于实例化阶段
public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
}
protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
// 单例 Bean 实例化前执行,将正要创建的 Bean 加入 singletonsCurrentlyInCreation 集合
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
// 单例 Bean 实例化后执行,从 singletonsCurrentlyInCreation 集合中移除已创建的 Bean
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
...
/********************* 6、 存储 Bean 之间的关系、判断 Bean 之间的关系 *********************/
// 保存具有包含关系的 Bean(内部类与外部类)
public void registerContainedBean(String containedBeanName, String containingBeanName) {
synchronized (this.containedBeanMap) {
Set<String> containedBeans =
this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
if (!containedBeans.add(containedBeanName)) {
return;
}
}
registerDependentBean(containedBeanName, containingBeanName);
}
// 保存具有依赖关系的 Bean
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
...
/***************************** 7、 销毁 Bean 的方法 *****************************/
...
}
1.2 ApplicationContext:IOC接口设计和实现
1.2.1 ApplicationContext整体类图
-
HierarchicalBeanFactory 和 ListableBeanFactory
ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,提供BeanFactory角色功能。 -
ApplicationEventPublisher
- 使容器具备发布应用上下文事件的功能,如容器启动事件、关闭事件等。
- 实现了
ApplicationListener
事件监听接口的 Bean 可以接收容器事件,并对事件进行响应处理。 - 在
AbstractApplicationContext
抽象实现类中存在ApplicationEventMulticaster
,负责保存所有监听器,通知监听者容器产生上下文事件。
-
MessageSource
为应用提供 i18n 国际化消息访问的功能。 -
ResourcePatternResolver
- 所有
ApplicationContext
实现类都提供类似于PathMatchingResourcePatternResolver
的功能。 - 可以通过带前缀的 Ant 风格的资源文件路径加载 Spring 的配置文件。
- 所有
-
LifeCycle
LifeCycle
接口是 Spring 2.0 引入的,提供start()
和stop()
两个方法,用于控制异步处理过程。- 在具体使用时,该接口被
ApplicationContext
实现及具体 Bean 实现。 ApplicationContext
会将start/stop
的信息传递给容器中所有实现了该接口的 Bean,以管理和控制 JMX、任务调度等目的。
1.2.2 ApplicationContext接口的实现
在考虑ApplicationContext接口的实现时,关键的点在于,不同Bean的配置方式(比如xml,groovy,annotation等)有着不同的资源加载方式,这便衍生除了众多ApplicationContext的实现类。
第一,从类结构设计上看, 围绕着是否需要Refresh容器衍生出两个抽象类:
- GenericApplicationContext: 是初始化的时候就创建容器,往后的每次refresh都不会更改
- AbstractRefreshableApplicationContext: AbstractRefreshableApplicationContext及子类的每次refresh都是先清除已有(如果不存在就创建)的容器,然后再重新创建;AbstractRefreshableApplicationContext及子类无法做到GenericApplicationContext混合搭配从不同源头获取bean的定义信息。
第二, 从加载的源来看(比如xml,groovy,annotation等), 衍生出众多类型的ApplicationContext, 典型比如:
- FileSystemXmlApplicationContext: 从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件。
- ClassPathXmlApplicationContext: 从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式。
- AnnotationConfigApplicationContext: 从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式。
- ConfigurableApplicationContext: 扩展于 ApplicationContext,它新增加了两个主要的方法: refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用close()则可关闭应用上下文。
这些接口方法为容器的控制管理带来了便利,但作为开发者,我们并不需要过多关心这些方法。
第三, 更进一步理解:设计者在设计时AnnotationConfigApplicationContext为什么是继承GenericApplicationContext?
因为基于注解的配置,是不太会被运行时修改的,这意味着不需要进行动态Bean配置和刷新容器,所以只需要GenericApplicationContext。而基于XML这种配置文件,这种文件是容易修改的,需要动态性刷新Bean的支持,所以XML相关的配置必然继承AbstractRefreshableApplicationContext; 且存在多种xml的加载方式(位置不同的设计),所以必然会设计出AbstractXmlApplicationContext, 其中包含对XML配置解析成BeanDefination的过程。
那么为什么AnnotationWebConfigApplicationContext却是继承了AbstractRefreshableApplicationContext而不是GenericApplicationContext ? 因为用户可以通过ApplicationContextInitializer来设置contextInitializerClasses(context-param / init-param), 在这种情况下用户倾向于刷新Bean的,所以设计者选择让AnnotationWebConfigApplicationContext继承了AbstractRefreshableApplicationContext。
如下是源码中Spring设计者对它的解释。
* <p>As an alternative to setting the "contextConfigLocation" parameter, users may
* implement an {@link org.springframework.context.ApplicationContextInitializer
* ApplicationContextInitializer} and set the
* {@linkplain ContextLoader#CONTEXT_INITIALIZER_CLASSES_PARAM "contextInitializerClasses"}
* context-param / init-param. In such cases, users should favor the {@link #refresh()}
* and {@link #scan(String...)} methods over the {@link #setConfigLocation(String)}
* method, which is primarily for use by {@code ContextLoader}.
2. Spring IOC容器初始化流程
整体流程如下所示:
2.1. SpringApplication.run(Application.class, args),实际调用new SpringApplication(null, primarySources).run(args)。
构造函数和run的实现如下。
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
可以看到SpringApplication类的构造方法主要是初始化应用类型(Reactive或Servlet)及通过SpringFactories机制实例化BootstrapRegistryInitializer、ApplicationContextInitializer及ApplicationListener的实现类。
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
// 创建IOC容器
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新IOC容器
refreshContext(context);
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
run方法除了读取环境变量、创建ApplicationContext容器createApplicationContext等操作,最主要的便是刷新ApplicationContext容器refreshContext,并穿插SpringApplication监听的开始启动、启动完成、准备事件。
2.2 refreshContext(ConfigurableApplicationContext context)方法实现如下,实际上是调用的传入的IOC容器的refresh()方法。
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
实际上会走到AbstractApplicationContext类的refresh()方法,代码如下。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
contextRefresh.end();
}
}
}
这里使用的模板方法设计模式,规定了需要执行的动作,且部分方法又子类进行实现。
其中,BeanFactory初始化一系列方法会读取文件/注解等完成BeanDefinition的反序列化及注入到beanDefinitionMap中,而finishBeanFactoryInitialization(beanFactory)方法完成了Bean生命周期的初始化操作。
2.3 finishBeanFactoryInitialization(beanFactory)
finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法实际调用的是AbstractApplicationContext类的实现,
由其中一行代码进入单例Bean的创建流程。
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
preInstantiateSingletons()则由DefaultListableBeanFactory类实现,代码如下。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("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.
// 通过beanDefinitionNames列表获取Bean的名字列表
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 通过BeanName从Map<String, RootBeanDefinition>获取BeanDefinition
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 如果Bean不是抽象的 是单例的 非懒加载的那么进行加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 工厂单例Bean的创建逻辑
if (isFactoryBean(beanName)) {
// 工厂Bean会有FACTORY_BEAN_PREFIX(值为&)前缀
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 普通单例Bean的创建逻辑
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 针对于实现了SmartInitializingSingleton接口的Bean调用接口实现的方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
2.4 getBean(String name)
其实可以看到,无论是针对于工厂Bean还是普通Bean,获取的方法都是getBean(String name),源码如下。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
2.5 doGetBean方法
而doGetBean方法的源码如下。
// 参数typeCheckOnly:bean实例是否包含一个类型检查
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 无参单例从缓存中获取
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果bean实例还在创建中,则直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果 bean definition 存在于父的bean工厂中,委派给父Bean工厂获取
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 将当前bean实例放入alreadyCreated集合里,标识这个bean准备创建了
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 确保它的依赖也被初始化了.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep); // 初始化它依赖的Bean
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建Bean实例:单例
if (mbd.isSingleton()) {
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 创建Bean实例:原型
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 创建Bean实例:根据bean的scope创建
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
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);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
2.6 getSingleton方法
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
2.7 createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法
实际上调用的是AbstractAutowireCapableBeanFactory类的实现,有一句核心代码。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
2.8 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
也是调用的AbstractAutowireCapableBeanFactory类的实现。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
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.
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 {
populateBean(beanName, mbd, instanceWrapper);
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) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
标签:容器,String,Spring,beanName,bean,Bean,单例,new
From: https://www.cnblogs.com/kiper/p/17976507