初探Spring源码之Spring Bean的生命周期

写在前面的话:

  学无止境,写博客纯粹是一种乐趣而已,把自己理解的东西分享出去,不意味全是对的,欢迎指正!

  • Spring 容器初始化过程做了什么?
1 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  • 实例了一个 AnnotationConfigApplicationContext对象,Spring中出来注解Bean定义的类有两个:

AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex AnnotationConfigWebApplicationContextAnnotationConfigApplicationContext的web版本,两者的用法以及对注解的处理方式几乎没有什么差别,通过分析这个类我们知道注册一个bean到spring容器有两种办法一、直接将注解Bean注册到容器中:(参考)public void register(Class<?>... annotatedClasses)但是直接把一个注解的bean注册到容器当中也分为两种方法:

  1、在初始化容器时注册并且解析

  2、也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处理。

思考:为什么@profile要使用这类的第2种方法?

因为需要通过applicationContext.getEnvironment()这样的方式设置环境或者获取环境变量

二、通过扫描指定的包及其子包下的所有类扫描其实同上,也是两种方法,初始化的时候扫描,和初始化之后再扫描

 1 public AnnotationConfigApplicationContext() {//0
 2    /**
 3     * 父类的构造方法
 4     * 创建一个读取注解的Bean定义读取器
 5     * 什么是bean定义?BeanDefinition
 6     */
 7    this.reader = new AnnotatedBeanDefinitionReader(this); //1
 8 ?
 9    //可以用来扫描包或者类,继而转换成bd
10    //但是实际上我们扫描包工作不是scanner这个对象来完成的
11    //是spring自己new的一个ClassPathBeanDefinitionScanner
12    //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
13    this.scanner = new ClassPathBeanDefinitionScanner(this); //2
14 }

注意: * 初始化一个bean的读取和扫描器 * 何谓读取器和扫描器参考上面的属性注释

      * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()

    * 去注册配置类(javaconfig),并调用refresh()方法刷新容器,

    * 触发容器对注解Bean的载入、解析和注册过程

  • 实例化AnnotationConfigApplicationContext会先实例化父类GenericApplicationContext,然后初始化一个Bean工厂,DefaultListableBeanFactory

    1 public GenericApplicationContext() {
    2    this.beanFactory = new DefaultListableBeanFactory();
    3 }
  • 1处,实例化一个BeanDefinition读取器 AnnotatedBeanDefinitionReader
 1 /**
 2  *  这里的BeanDefinitionRegistry registry是通过在AnnotationConfigApplicationContext
 3  *  的构造方法中传进来的this
 4  *  由此说明AnnotationConfigApplicationContext是一个BeanDefinitionRegistry类型的类
 5  *  何以证明我们可以看到AnnotationConfigApplicationContext的类关系:
 6  *  GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
 7  *  看到他实现了BeanDefinitionRegistry证明上面的说法,那么BeanDefinitionRegistry的作用是什么呢?
 8  *  BeanDefinitionRegistry 顾名思义就是BeanDefinition的注册器
 9  *  那么何为BeanDefinition呢?参考BeanDefinition的源码的注释
10  * @param registry
11  */
12 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
13    this(registry, getOrCreateEnvironment(registry));
14 }
15     public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
16       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
17       Assert.notNull(environment, "Environment must not be null");
18       this.registry = registry;
19       this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
20       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
21    }

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

1 public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
2    registerAnnotationConfigProcessors(registry, null);

以上空壳方法,调用以下方法

1 1 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
2 2       BeanDefinitionRegistry registry, @Nullable Object source) {
3 3 //主要是为了获得工厂对象,实例化AnnotationConfigApplicationContext的时候会调用父类
4 4 //GenericApplicationContext的构造器去实例化DefaultListableBeanFactory
5 5 //这里的registry其实际是GenericApplicationContext的子类实例,向上转型取得工厂的属性
6 6 //从而得到 beanFactory对象
7 7 DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

获得工厂的具体逻辑

private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {
   if (registry instanceof DefaultListableBeanFactory) {
      return (DefaultListableBeanFactory) registry;
   }
   else if (registry instanceof GenericApplicationContext) {
      //这里在AnnotationConfigApplicationContext初始化的时候this()
      //方法中调用了父类GenericApplicationContext的时候new了一个DefaultListableBeanFactory对象
      //下面代码返回这个对象
      return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();
   }
   else {
      return null;
   }
}

这段代码主要是为解析是否含有需要排序的注解

 1 if (beanFactory != null) {
 2    if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
 3       //AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
 4       beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
 5    }
 6    if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
 7       //ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
 8       beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
 9    }
10 }

org.springframework.context.annotation.internalConfigurationAnnotationProcessor这个是BeanDefinition

的一个beanName, 具体的类是ConfigurationClassPostProcessor,它在BeanDefinition中表现的是一个后置处理器(重要),是Spring的核心类之一。

 1 Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
 2 //BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型
 3 //org.springframework.context.annotation.internalConfigurationAnnotationProcessor
 4 //这个是spring生命周期非常重要的一个类
 5 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
 6    //需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
 7    //而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
 8    //因此需要对这两种类型的进行区分处理
 9 ?
10    //将一个类变成BeanDefinition
11    RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
12    def.setSource(source);
13    //这里是将BD注册到BeanFactory的BeanDefinitionMap容器中,并返回一个
14    //BeanDefinitionHolder对象
15    beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
16 }

实际上上面的代码和以下的代码主要往DefaultListableBeanFactory中的beanDefinitionMap 中放入以下所列举的6个后置处理器。其中ConfigurationClassPostProcessor是核心

0.org.springframework.context.annotation.ConfigurationClassPostProcessor(重要)

1.org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

2.org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor

3.org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

4.org.springframework.context.event.EventListenerMethodProcessor

5.org.springframework.context.event.DefaultEventListenerFactory

 1 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
 2    //AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
 3    //MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
 4    RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
 5    def.setSource(source);
 6    beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
 7 }
 8 ?
 9 if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
10    RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
11    def.setSource(source);
12    beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
13 }
14 ?
15 // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
16 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
17    RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
18    def.setSource(source);
19    beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
20 }
21 ?
22 // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
23 if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
24    RootBeanDefinition def = new RootBeanDefinition();
25    try {
26       def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
27             AnnotationConfigUtils.class.getClassLoader()));
28    }
29    catch (ClassNotFoundException ex) {
30       throw new IllegalStateException(
31             "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
32    }
33    def.setSource(source);
34    beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
35 }
36 ?
37 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
38    RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
39    def.setSource(source);
40    beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
41 }
42 ?
43 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
44    RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
45    def.setSource(source);
46    beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
47 }

疑问1:普通的对象是怎么变成BeanDefinition的呢?

//将一个类变成BeanDefinition
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);

疑问2:对象变成Beandefinition之后又是怎么注册到bean工厂的呢?

1 private static BeanDefinitionHolder registerPostProcessor(
2       BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
3 ?
4    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
5    //将bd注册到工厂的BeanDefinitionMap中
6    registry.registerBeanDefinition(beanName, definition);
7    //BeanDefinitionHolder 只是封装参数使用
8    return new BeanDefinitionHolder(definition, beanName);
9 }

registry.registerBeanDefinition(beanName, definition);这句代码将Beandefinition注册到BeanFactory中

注意这里的registry注册器一直都是AnnotationConfigApplicationContext对象,该类中没有registerBeanDefinition() ,因此会调用父类GenericApplicationContext的registerBeanDefinition()方法注册Beandefinition。

1 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
2       throws BeanDefinitionStoreException {
3 ?
4    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
5 }

调用org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition()的方法执行以下逻辑

1 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
2       throws BeanDefinitionStoreException {

不管GenericBeanDefinition,还是RootBeanDefinition都继承了AbstractBeanDefinition,因此会执行以下逻辑

 1 Assert.notNull(beanDefinition, "BeanDefinition must not be null");
 2 //BeanDefinition的所有实现类都继承了AbstractBeanDefinition,因此会执行以下的检验逻辑
 3 if (beanDefinition instanceof AbstractBeanDefinition) {
 4    try {
 5       ((AbstractBeanDefinition) beanDefinition).validate();
 6    }
 7    catch (BeanDefinitionValidationException ex) {
 8       throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
 9             "Validation of bean definition failed", ex);
10    }
11 }

执行一些逻辑判断,打印一些log,这些不重要

 1 //根据beanName从容器中取出BD,判断是否已经注册了的各种校验
 2 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
 3 if (existingDefinition != null) {
 4     //是否允许覆盖原有的bean 默认是不覆盖
 5    if (!isAllowBeanDefinitionOverriding()) {
 6       throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
 7             "Cannot register bean definition [" + beanDefinition + "] for bean ‘" + beanName +
 8             "‘: There is already [" + existingDefinition + "] bound.");
 9    }
10    else if (existingDefinition.getRole() < beanDefinition.getRole()) {
11       // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
12       if (logger.isWarnEnabled()) {
13          logger.warn("Overriding user-defined bean definition for bean ‘" + beanName +
14                "‘ with a framework-generated bean definition: replacing [" +
15                existingDefinition + "] with [" + beanDefinition + "]");
16       }
17    }
18    else if (!beanDefinition.equals(existingDefinition)) {
19       if (logger.isInfoEnabled()) {
20          logger.info("Overriding bean definition for bean ‘" + beanName +
21                "‘ with a different definition: replacing [" + existingDefinition +
22                "] with [" + beanDefinition + "]");
23       }
24    }
25    else {
26       if (logger.isDebugEnabled()) {
27          logger.debug("Overriding bean definition for bean ‘" + beanName +
28                "‘ with an equivalent definition: replacing [" + existingDefinition +
29                "] with [" + beanDefinition + "]");
30       }
31    }
32     //加入到beanDefinitionMap当中,正常第一次不会走到这里
33    this.beanDefinitionMap.put(beanName, beanDefinition);
34 }
35 else {
36    if (hasBeanCreationStarted()) {
37       // Cannot modify startup-time collection elements anymore (for stable iteration)
38       synchronized (this.beanDefinitionMap) {
39           //这里加锁的意义是防止正在创建的Bean被修改。
40          this.beanDefinitionMap.put(beanName, beanDefinition);
41          List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
42          updatedDefinitions.addAll(this.beanDefinitionNames);
43          updatedDefinitions.add(beanName);
44          this.beanDefinitionNames = updatedDefinitions;
45          if (this.manualSingletonNames.contains(beanName)) {
46             Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
47             updatedSingletons.remove(beanName);
48             this.manualSingletonNames = updatedSingletons;
49          }
50       }
51    }

初次注册BeanDefinition的会执行

1 else {
2    // Still in startup registration phase
3     //初次注册会执行这段逻辑,90%的注册会走到这里
4    this.beanDefinitionMap.put(beanName, beanDefinition);
5    this.beanDefinitionNames.add(beanName);
6    this.manualSingletonNames.remove(beanName);
7 }
8 this.frozenBeanDefinitionNames = null;

至此,实例化一个AnnotationBeanDefinitionReader会注册6个后置处理器,为什么注册这些后置处理器,有什么作用,会在后续的Spring源码解析中进行讲解。另外核心的类ConfigurationClassPostProcessor的作用是什么?

  • 2处,实例化一个BeanDefinition 扫描器ClassPathBeanDefinitionScanner

    BeanDefinition扫描器这里不做多介绍,因为这里的扫描器主要是为了给程序员自己定义一个类的扫描器,用来扫描我们自定义的加了注解类。

    疑问3:Spring是怎么扫描被注解标识的类呢?

  • 如加了@Component @Controller @Service @Repository 等等,其实用的也是ClasspathBeanDefinitionScanner,只不过Spring内部它自己实例化了一个,并不是用的这里这个而已,后续会进行解析和讲解。

原文地址:https://www.cnblogs.com/codecaicai/p/10633448.html

时间: 2024-08-27 00:09:15

初探Spring源码之Spring Bean的生命周期的相关文章

Spring笔记——6.容器中bean的生命周期

spring可以管理单例bean的生命周期,知道何时被创建,核实初始化,何时销毁,也可以进行某些通用资源申请,销毁前资源回收.对于prototype,容器只负责创建,之后就撒手不管自生自灭.容器不知道一共创建了多少prototype,也不知道他们什么时候会被销毁,所以容器没法管理prototype. 管理bean的生命周期有如下两个时机: 注入依赖关系后 即将销毁bean前 依赖关系注入后的行为 通过设定init-method属性指定某个方法或者实现InitializingBean接口指定需要实

【Spring源码分析】Bean加载流程概览

代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事的都是Java Web的工作,对于程序员来说,一个Web项目用到Spring,只是配置一下配置文件而已,Spring的加载过程相对是不太透明的,不太好去找加载的代码入口. 下面有很简单的一段代码可以作为Spring代码加载的入口: 1 ApplicationContext ac = new Clas

spring源码阅读(二) Bean加载之自定义标签加载

紧接着上一篇关于spring默认标签加载,这一篇来看下自定义标签的加载 继续从 DefaultBeanDefinitionDocumentReader来看 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for(

『互联网架构』软件架构-spring源码之spring结构概述

spring从07年接触到目前2018年也差不多10年了,一个java的框架为什么能火这么多年.很多人对spring的使用轻车熟路,但是从未解读过spring的源码,老铁跟我一起看看源码,了解下内部的构造,只有源码读过的人才能获得上乘武功,软件开发不只是搬砖的老铁.内功熟悉原理,外功是灵活使用.内功好比电力,外功好比电机.内功的电力越强,电机的马力越大才能发挥巨大作用,相反如果电力弱,马力在强也是不行的.spring从单一的jar包,发展到现在十多个jar包,spring mvc 到spring

spring源码系列——spring循环引用

众所周知spring在默认单例的情况下是支持循环引用的 Appconfig.java类的代码 @Configurable@ComponentScan("com.shadow")public class Appconfig {}1234X.java类的代码 package com.shadow.service; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.

spring源码解析——spring源码导入eclipse

一.前言     众所周知,spring的强大之处.几乎所有的企业级开发中,都使用了spring了.在日常的开发中,我们是否只知道spring的配置,以及简单的使用场景.对其实现的代码没有进行深入的了解.开卷有益,在我们空闲的时间里面阅读一下spring的源码,对提升我们的自身能力还是还有很大的帮忙.下面总结一下spring源码导入eclipse的具体的操作. 二.spring的特点 spring的的核心就是IOC(控制反转)和AOP(基于切面的编程) 事务管理方面采用了:声明式事务 为各种主流

Spring 框架基础(02):Bean的生命周期,作用域,装配总结

本文源码:GitHub·点这里 || GitEE·点这里 一.装配方式 Bean的概念:Spring框架管理的应用程序中,由Spring容器负责创建,装配,设置属性,进而管理整个生命周期的对象,称为Bean对象. 1.XML格式装配 Spring最传统的Bean的管理方式. 配置方式 <bean id="userInfo" class="com.spring.mvc.entity.UserInfo"> <property name="na

spring源码阅读之Bean的加载(二)

在正式分析源码之前,先来了解一下SpringBeans里面最核心的两个类  DefaultListableBeanFactory XMLBean继承自 DefaultListableBeanFactory,而 DefaultListableBeanFactory是整个Bean加载的核心部分,是Sprin注册及加载Bean的默认实现,而对于XmlBeanFactory与 DefaultListableBeanFactory不同的地方其实就是在XmlBeanFactory中使用了自定义的XML读取器

【spring源码】spring web 启动与关闭

web.xml中有这么一段声明 <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.c