Spring Bean生命周期详细分析

目录
  • 前言
  • 一、Bean的介绍
    • 什么是Bean
    • Bean的生命周期
    • Bean的作用域
  • 二、详细过程
    • 1. Bean的实例化
    • 2. InstantiationAwareBeanPostProcessor
    • 3. 设置属性(依赖注入)
    • 4. 注入Aware接口
    • 5. BeanPostProcessor的postProcessBeforeInitialzation方法
    • 6. InitializingBean与init-method
    • 7. BeanPostProcess的postProcessAfterInitialzation方法
    • 8. Bean初始化结束
    • 9. DispostbleBean接口

前言

Bean的生命周期分为实例化Instantiation、属性赋值Populate、初始化Initalization、销毁Destruction,下面我将从这四个方面深入分享Bean的生命周期。

一、Bean的介绍

我们首先来看看spring的两大核心思想IOC(控制反转),DI(依赖注入)和AOP (面向切面编程)

IOC(控制反转):是Spring框架的核心思想之一,主要用于解耦。I0C是指将创建对象的控制权转移给Spring框架进行管理。由Spring框架根据配置文件或注解等元数据,创建bean对象并管理各个bean对象之间的依赖关系。使对象之间形成松散耦合的关系,利于解耦。

DI(依赖注入):是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个bean对象都依赖IOC容器注入当前bean对象所需要的另外一-个bean对象。(例如在MyBatis整合Spring时,SqISessionFactoryBean依赖容器注入-个DataSource数据源)

IOC容器:IOC容器属于SpringCore模块,是用来创建和管理Bean的地方,以默认单例的方式将bean存储在以ConcurrentHashMap的形式存储了BeanDefinition对象,该对象封装了Spring对一个Bean所有信息的定义,包括类名,属性,构造方法参数,依赖,是否延迟加载,是否单例等,之后对Bean的操作都是直接对它进行的。

IOC容器的初始化分三个步骤:

  • BeanDefinition的资源定位
  • BeanDefinition的资源的载入和解析
  • BeanDefinition的注册

AOP (面向切面编程):SpringAOP基于动态代理实现。能够将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

什么是Bean

bean是计算机自动生成的类,bean是一个由SpringIoC容器实例化、组装和管理的对象。也就是说,bean并不是程序员编辑的,而是程序运行时,由spring通过反射生成的

Bean的生命周期

实例化->属性赋值->初始化->销毁

Bean的作用域

singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。

prototype : 每次请求都会创建一个新的 bean 实例。

request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。

session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。

global-session: 全局 session 作用域,仅仅在基于 Portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。

二、详细过程

实例化和属性赋值分别对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。

可通过查源码的方式发现,他们都在doCreate()方法中,如下:

//可通过查源码的方式发现,他们都在doCreate()方法中,
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 实例化阶段!
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 属性赋值阶段!
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化阶段!
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

1. Bean的实例化

Spring对Bean进行实例化(相当于 new XXX()),对于 BeanFactory一般是延迟实例化,就是说调用 getBean方法才会实例化,但是对于 ApplicationContext,当容器初始化完成之后,就完成了所有Bean的实例化工作。实例化的对象被包装在 BeanWrapper对象中, BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性。

2. InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor这个接口主要是帮助你在Bean实例化之前做一些操作。它继承自 BeanPostProcessor接口,其中 postProcessBeforeInstantiation()方法是在目标对象实例化之前调用的方法,可以返回目标实例的一个代理用来代替目标实例。postProcessPropertyValues方法是在属性值被设置到目标实例之前调用,可以修改属性的设值。

3. 设置属性(依赖注入)

实例化后的对象被封装到 BeanWrapper对象中,并且此时对象是一个原生状态,并没有执行依赖注入。紧接着,Spring根据 BeanDefinition中的信息进行依赖注入。并且通过 BeanWrapper提供的设置属性的接口完成依赖注入。

4. 注入Aware接口

Spring 会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean。各种各样的Aware接口,其作用就是在对象实例化完成后将Aware接口定义中规定的依赖注入到当前实例中。比较常见的 ApplicationContextAware接口,实现了这个接口的类都可以获取到一个 ApplicationContext对象,当容器中每个对象的实例化过程走到 BeanPostProcessor前置处理这一步时,容器会检测到之前注册到容器的 ApplicationContextAwareProcessor,然后就会调用其 postProcessorBeforeInitialization()方法,检查并设置Aware相关的依赖。

5. BeanPostProcessor的postProcessBeforeInitialzation方法

经过上述步骤后,Bean对象已经被正确构造了,如果你想要对象被使用之前在进行自定义的处理,可以通过 BeanPostProcessor接口实现。该接口提供了两个方法 其中 postProcessBeforeInitialzation(Objectbean,StringbeanName) 方法;当前正在初始化的bean对象会被传递进来,我们就可以对这个Bean做任何处理,这个方法会先于 InitializingBean执行,因此称为前置处理。

6. InitializingBean与init-method

如果Bean实现了 InitializingBean接口,Spring将调用它们的 afterPropertiesSet方法,作用与在配置文件中对Bean使用 init-method声明初始化的作用一样,都是在Bean的全部属性设置成功后执行的初始化方法。afterPropertiesSet 方法与前置处理不同的是,由于其没有把Bean对象传进来,因此在这一步没有办法处理对象本身,只能增加一些额外的逻辑。

7. BeanPostProcess的postProcessAfterInitialzation方法

BeanPostProcesspostProcessAfterInitialzation(Objectbean,StringbeanName) 方法;当前正在初始化的bean对象会被传递进来,我们就可以对这个bean做任何处理。这个函数会在 InitializingBean完成后执行,因此称为后置处理。

8. Bean初始化结束

经过以上的工作以后,Bean的初始化就结束了,Bean将一直驻留在应用上下文中给应用使用,知道应用上下文被销毁。

9. DispostbleBean接口

如果Bean实现了 DispostbleBean接口,Spring将调用它的 destroy方法,作用与在配置文件中对Bean使用 destroy-method属性的作用是一样的,都是在Bean实例销毁前执行的方法。

最后的最后用我多年画工附一张如给大家康康:

到此这篇关于Spring Bean生命周期详细分析的文章就介绍到这了,更多相关Spring Bean生命周期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring Bean作用域与生命周期深入讲解

    目录 1.作用域定义 Bean 的作用域 Bean 的 6 种作用域 单例作用域(singleton)和全局作用域(application)区别 2.设置作用域 3.Bean 原理分析 3.1 Bean(Spring)执行流程 3.2 Bean生命周期 1.作用域定义 限定程序中变量的可用范围叫做作用域,或者说在源代码中定义变量的某个区域就叫做作用域. Bean 的作用域 而 Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式,比如 singleton 单例作用域,就表

  • 深入了解Spring的Bean生命周期

    目录 源码下载 什么是 Spring Bean 的生命周期 Bean的生命周期 Spring角度查看bean的定义与注册 SpringBoot角度查看bean定义和注册 实例化,依赖注入,初始化 Bean的生命周期的扩展点 Bean级别 容器级别 常用接口 InstantiationAwareBeanPostProcessor BeanNameAware BeanFactoryAware ApplicationContextAware BeanPostProcessor Initializing

  • Java Spring Bean的生命周期管理详解

    目录 Spring Bean的生命周期管理 一.Spring Bean的生命周期 二.通过@Bean的参数(initMethod ,destroyMethod)指定Bean的初始化和销毁方法 1.项目结构 2.Person 3.Bean注册配置类(单实例) 4.测试类 5.测试结果 6.Bean注册配置类(多实例) 7.测试结果 三.Bean实现接口InitializingBean, DisposableBean 1.Person 2.Bean注册配置类 3.测试结果 四.通过注解@PostCo

  • Java之SpringBean生命周期问题理解

    Spring Bean的生命周期? 首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy: Spring上下文中的Bean生命周期也类似,如下: (1)实例化Bean: 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化.对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中

  • 一文搞懂Spring中Bean的生命周期

    目录 一.使用配置生命周期的方法 二.生命周期控制——接口控制(了解) 小结 生命周期:从创建到消亡的完整过程 bean声明周期:bean从创建到销毁的整体过程 bean声明周期控制:在bean创建后到销毁前做一些事情 一.使用配置生命周期的方法 在BookDaoImpl中实现类中创建相应的方法: //表示bean初始化对应的操作 public void init(){ System.out.println("init..."); } //表示bean销毁前对应的操作 public v

  • Spring中Bean的作用域与生命周期详解

    目录 一.Bean的作用域 1.单实例Bean声明 2.多实例Bean声明 二.Bean的生命周期 1.bean的初始和销毁 2.bean的后置处理器 总结 一.Bean的作用域 首先我们来讲一下有关于bean的作用域, 一般情况下,我们书写在IOC容器中的配置信息,会在我们的IOC容器运行时被创建,这就导致我们通过IOC容器获取到bean对象的时候,往往都是获取到了单实例的Bean对象, 这样就意味着无论我们使用多少个getBean()方法,获取到的同一个JavaBean都是同一个对象,这就是

  • 详解Spring中Bean的作用域与生命周期

    目录 一.Bean的作用域 二.Bean的生命周期 使用代码演示Bean的生命周期 一.Bean的作用域 通过Spring容器创建一个Bean的实例时,不仅可以完成Bean的实例化,还可以使用Bean的scope属性为bean设置作用域. 语法格式:<bean id="别名" scope="作用域" class="对应实现类"> 作用域的种类:(sing) singleton和prototype区别:(该两种比较常用) ① singl

  • Java Spring中Bean的作用域及生命周期

    目录 1.Bean的作用域 1.1 被修改的Bean案例 1.2 为什么使用单例模式作为默认作用域 1.3 作用域 1.4 Bean的6种作用域 1.5 设置作用域 2.Spring执行流程和Bean的生命周期 2.1 Bean的生命周期 2.1.1生命周期演示 2.1.2 为什么要先设置属性,在进行初始化 1.Bean的作用域 1.1 被修改的Bean案例 原因:Bean的作用域默认是单例模式的,也就是说所有⼈的使⽤的都是同⼀个对象!之前我们学单例模式的时候都知道,使⽤单例可以很⼤程度上提⾼性

  • 一文搞懂Spring Bean中的作用域和生命周期

    目录 一.Spring Bean 作用域 singleton(单例) prototype(原型) 小结 二.Spring Bean生命周期 如何关闭容器 生命周期回调 通过接口设置生命周期 通过xml设置生命周期 一.Spring Bean 作用域 常规的 Spring IoC 容器中Bean的作用域有两种:singleton(单例)和prototype(非单例) 注:基于Web的容器还有其他种作用域,在这就不赘述了. singleton(单例) singleton是Spring默认的作用域.当

  • Spring Bean生命周期详细分析

    目录 前言 一.Bean的介绍 什么是Bean Bean的生命周期 Bean的作用域 二.详细过程 1. Bean的实例化 2. InstantiationAwareBeanPostProcessor 3. 设置属性(依赖注入) 4. 注入Aware接口 5. BeanPostProcessor的postProcessBeforeInitialzation方法 6. InitializingBean与init-method 7. BeanPostProcess的postProcessAfterI

  • 谈谈我对Spring Bean 生命周期的理解

    前言 Spring的ioc容器功能非常强大,负责Spring的Bean的创建和管理等功能.而Spring 的bean是整个Spring应用中很重要的一部分,了解Spring Bean的生命周期对我们了解整个spring框架会有很大的帮助. BeanFactory和ApplicationContext是Spring两种很重要的容器,前者提供了最基本的依赖注入的支持,而后者在继承前者的基础进行了功能的拓展,例如增加了事件传播,资源访问和国际化的消息访问等功能.本文主要介绍了ApplicationCo

  • 全面详解Spring Bean生命周期教程示例

    目录 Spring 中 Bean 的生命周期 Bean 的实例化 构造方法注入 工厂方法注入 Bean 的属性赋值 setter注入 构造方法注入 Bean 的初始化 初始化方法 InitializingBean 接口 Bean 的销毁 销毁方法 DisposableBean 接口 总结 Spring 中 Bean 的生命周期 是当今最流行的 Java 开发框架之一,其强大的 Bean容器机制是其中的核心之一.Bean 是指在 Spring 容器中被管理的对象,它们可以被注入到其他对象中,也可以

  • 浅谈Spring bean 生命周期验证

    一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware setBeanName 设置bean名称 2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器 3.BeanFactoryAware setBeanFactory 设置bean工厂 4.EnvironmentAware setEnvironment

  • Spring Bean生命周期源码原理图解

    概述 spring流行了很长时间了,是一个用java编写的轻量级框架,受到了很多公司及程序员的欢迎,Bean生命周期是一个对象从实例化开始到销毁的全过程,了解生命周期是很有必要的. 重要性 spring的生命周期是比较复杂的,只有了解其过程及原理才能更好的扩展程序. 源码剖析生命周期过程bean的实例化 属性填充及Aware接口检测设置依赖 如果容器自定义了BeanpostProcessor的实现类,则执行处理器相应的前置处理 bean实现了初始化接口InitlializingBean,则会执行

  • Spring Bean生命周期之Bean的实例化详解

    目录 前言 实例化前阶段 实例化阶段 实例化后阶段 总结 前言 上一节说到了BeanDefinition的合并过程,这节该说Bean的实例化过程了.根据AbstractAutowireCapableBeanFactory#createBean源码逻辑 可将实例化过程分为实例化前阶段.实例化过程.实例化后阶段. 实例化前阶段 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[]

  • Spring Bean生命周期之Bean元信息的配置与解析阶段详解

    目录 BeanDefinitionReader体系 BeanDefinitionReader接口定义 元信息配置与解析方式 XmlBeanDefinitionReader元信息解析源码分析 AnnotatedBeanDefinitionReader元信息解析源码分析 总结 写在前面 注:本文章使用的 SpringBoot 版本为 2.2.4.RELEASE,其 Spring 版本为 5.2.3.RELEASE 虽然Bean的创建可以采用BeanDefinition API 也可以直接采用注解方式

  • Spring Bean生命周期之BeanDefinition的合并过程详解

    目录 前言 BeanDefinition的合并源码分析 总结 写在前面 注:本文章使用的 SpringBoot 版本为 2.2.4.RELEASE,其 Spring 版本为 5.2.3.RELEASE 前言 书接上文,BeanDefinition注册到IoC容器后,紧接着就是要使用Bean了,要使用必须先要获取Bean,这里我们就以DefaultListableBeanFactory#getBean方法来引出本次讨论的内容:BeanDefinition的合并 通过前面的章节我们了解到了BeanD

  • Spring Bean生命周期之Bean的注册详解

    目录 前言 BeanFactory的继承体系 Bean的注册 alias别名的注册 总结 前言 上篇文章介绍了Bean元信息的配置与解析过程,限于篇幅Bean注册过程就没展开. 这里主要围绕BeanDefinitionReaderUtils#registerBeanDefinition展开分析下Bean注册过程 public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinit

  • Spring Bean生命周期之属性赋值阶段详解

    目录 前言 属性自动装配 属性赋值前回调 属性的真正赋值 总结 前言 上节在谈论Bean的实例化过程时,在说明实例化后阶段时只是粗略地看了一下populateBean,并未展开分析.本节接着populateBean开始分析对象赋值阶段的事情. populateBean其实主要做了以下几件事: Bean实例化后回调,来决定是否进行属性赋值 (上节分析过了) 对属性进行自动装配 InstantiationAwareBeanPostProcessor属性赋值前回调 属性的真正赋值 protected

随机推荐