Spring中的容器和Bean
- 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)方法
在doGetBean方法中,可以看到传入了一个回调函数,而其中的createBean(beanName, mbd, args)才是真正创建Bean的方法。
// 创建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); }
doCreateBean方法实际上调用的是AbstractAutowireCapableBeanFactory类的实现,有一句核心代码。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
2.8 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
doCreateBean方法也是调用的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; }
可以看到几行关键代码。
-
instanceWrapper = createBeanInstance(beanName, mbd, args);
调用构造器反射创建Bean对象完成实例化. -
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
执行MergedBeanDefinitionPostProcessor接口的实现类,比如AutowiredAnnotationBeanPostProcessor 是 MergedBeanDefinitionPostProcessor 的一个实现类,它可用于完成 Autowire 注解的依赖注入。可以参考Spring 的 MergedBeanDefinition 后处理器。 -
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
添加Bean到三级缓存,源码如下。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); } } } -
populateBean(beanName, mbd, instanceWrapper);
属性填充。InstantiationAwareBeanPostProcessor接口扩展点在这里执行,并且发现有AutoWire注入的属性,会通过getBean方法进行获取。
核心源码如下。if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } -
exposedObject = initializeBean(beanName, exposedObject, mbd);
Bean的初始化,会进行Aware方法的设置,调用BeanPostProcessor接口的两个方法实现及Bean的init方法。
源码如下。protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { 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()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } 其中,
invokeAwareMethods(beanName, bean);
源码如下。private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?