一文读懂 Bean的生命周期

简介: 一文读懂 Bean的生命周期

前言:

日月更替,周而复始,大自然中的任何生命都有着它的周期,比如蚂蚁的寿命只有几年,而乌龟的寿命却有几十年甚至上百年。


同理,在Spring框架中,Bean对象也有着它的生命周期,然而对于Bean对象的生命周期,我们并不是很清楚,因为Spring帮助我们管理了Bean对象,所以,掌握Bean的生命周期,并知晓Spring在每个阶段为我们做了哪些事情是非常有必要的。


Spring Bean的生命周期,你了解吗!好啦那我们一起来了解Bean生命周期!!!

一.什么是Bean的生命周期

bean的生命周期指的是:bean创建-->初始化-->销毁 的过程,bean的生命周期由容器进行管理,我们可以自定义bean的初始化和销毁方法来满足我们的需求,当容器在bean进行到当前生命周期的时候,来调用自定义的初始化和销毁方法。


在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。


相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程:

  1.  Spring 对bean 进行实例化。
  2.  Spring 将值和bean的引用注入到bean对应的属性中。
  3.  如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()  方法。       (实现BeanNameAware清主要是为了通过Bean的引用来获得Bean的ID,一般业务中是很少有用到Bean的ID的)
  4.  如果bean 实现了BeanFactoryAware接口,Spring将调用setBeanFactory() 方法,将BeanFactory容器实例传入。     (实现BeanFactoryAware 主要目的是为了获取Spring容器,如Bean通过Spring容器发布事件等)
  5.  如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext() 方法,将bean所在的应用上下文的引用传入进来。(作用与BeanFactory类似都是为了获取Spring容器,不同的是Spring容器在调用setApplicationContext方法时会把它自己作为setApplicationContext 的参数传入,而Spring容器在调用setBeanDactory前需要程序员自己指定(注入)setBeanDactory里的参数BeanFactory )
  6.  如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization() 方法     (作用是在Bean实例创建成功后对进行增强处理,如对Bean进行修改,增加某个功能)
  7.  如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用。
  8.  如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization() 方法。    (作用与6的一样,只不过6是在Bean初始化前执行的,而这个是在Bean初始化后执行的,时机不同 )
  9.  此时, bean 已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁。
  10.  如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。


二.Bean的核心生命周期

虽然spring提供了大量Bean级生命周期接口和容器级生命空间接口来扩展bean的生命周期,但bean的核心生命周期只有四个阶段:

1.实例化 Instantiation


doCreateBean中调用createBeanInstance() 方法


2.属性赋值 Populate


doCreateBean中调用populateBean() 方法


3.初始化 Initialization


doCreateBean中调用initializeBean() 方法


4.销毁 Destruction


对于scope=singleton的Bean (prototype不会触发销毁),当容器关闭时,会触发bean的销毁。


三.Bean的单例与多例模式

3.1.什么是单例与多例

在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)

singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。

prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。

Spring bean默认是单例模式。

3.2.单例与多例bean的生命周期

  • 单实例下 bean的生命周期

容器启动——>初始化方法——>(容器关闭)销毁方法

  • 多实例下 bean的生命周期

容器启动——>调用bean——>初始化方法——>容器关闭(销毁方法不执行)

3.3.单例与多例的演示

单例模式:

package com.junlinyi.beanLife;
import java.util.List;
public class ParamAction {
  private int age;
  private String name;
  private List<String> hobby;
  private int num = 1;
  public ParamAction() {
    super();
  }
  public ParamAction(int age, String name, List<String> hobby) {
    super();
    this.age = age;
    this.name = name;
    this.hobby = hobby;
  }
  public void execute() {
    System.out.println("this.num=" + this.num++);
    System.out.println(this.name);
    System.out.println(this.age);
    System.out.println(this.hobby);
  }
}

测试一手:

package com.junlinyi.beanLife;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
 * spring bean的生命週期
 * spring bean的單例多例
 *
 */
public class Demo2 {
  // 体现单例与多例的区别
  @Test
  public void test1() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
    ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
    p1.execute();
    p2.execute();
//    单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
    applicationContext.close();
  }
}

spring配置文件:

<!--    bean的生命周期-->
    <bean id="paramAction" class="com.junlinyi.beanLife.ParamAction">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

结果:

由于我们默认使用的是单例模式,所以在运行时出现了变量污染,num值变为2

Bean工厂:

package com.junlinyi.beanLife;
public class InstanceFactory {
  public void init() {
    System.out.println("初始化方法");
  }
  public void destroy() {
    System.out.println("销毁方法");
  }
  public void service() {
    System.out.println("业务方法");
  }
}

测试一手:

package com.junlinyi.beanLife;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
 * spring bean的生命週期
 * spring bean的單例多例
 *
 */
public class Demo2 {
  // 体现单例与多例的初始化的时间点 instanceFactory
  @Test
  public void test2() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
  }
}

spring配置上下文:

<bean id="instanceFactory" class="com.junlinyi.beanLife.InstanceFactory"
          scope="singleton" init-method="init" destroy-method="destroy"></bean>

.单例模式中的JavaBean是跟着Spring上下文初始化的,容器生成对象跟着生成,容器死亡,对象死亡

多例模式:

将spring配置文件中指定scope为prototype

<bean id="paramAction" class="com.junlinyi.beanLife.ParamAction" scope="prototype">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="instanceFactory" class="com.xissl.beanLife.InstanceFactory"
          scope="prototype" init-method="init" destroy-method="destroy"></bean>

结果:

多例模式走的Javabean是使用时才会创建,销毁要跟着Jvm走:

   好啦,今天的分享就到这了,希望能够帮到你呢!😊😊  

目录
相关文章
|
3月前
|
人工智能 监控 数据挖掘
企业级Agent解决方案:从单点突破到全域协同的 AgentOne 解决方案
2026年,AI成企业增长刚需。阿里云瓴羊推出企业级Agent解决方案:以AgentOne为智能中枢,融合Quick Audience(营销)、Quick Service(客服)、智能小Q(BI)及Dataphin(数据底座),打破工具孤岛与数据壁垒,实现跨场景协同、私有化推理与安全可控的“数字员工团队”,加速企业从数字化迈向数智化跃迁。(239字)
|
存储 算法 分布式数据库
【数据结构】二叉树的顺序结构实现及时间复杂度计算(二)
【数据结构】二叉树的顺序结构实现及时间复杂度计算(二)
505 0
|
5月前
|
人工智能 自然语言处理 算法
希望国内AI不要作恶,不要变成百度
国内AI常引用营销号,而GPT多引官网与权威报告,根源在于信源标准的代差。本文揭示中文互联网“脏数据”环境如何导致AI沦为信息扩音器,并提出建立“AI-Rank”价值体系,以信源加权、逻辑检测与交叉验证重构答案可信度,呼吁AI厂商肩负文明责任,打造真理裁判长。
405 9
|
消息中间件 存储 Kafka
RocketMQ 工作原理图解,看这篇就够了!
本文详细解析了 RocketMQ 的核心架构、消息领域模型、关键特性和应用场景,帮助深入理解消息中间件的工作原理。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
RocketMQ 工作原理图解,看这篇就够了!
|
存储 安全 Java
synchronized原理详解(通俗易懂超级好)
当系统检查到锁是重量级锁之后,会把等待想要获得锁的线程进行阻塞,被阻塞的线程不会消耗cpu。但是阻塞或者唤醒一个线程时,都需要操作系统来帮忙,这就需要从用户态转换到内核态,而转换状态是需要消耗很多时间的,有可能比用户执行代码的时间还要长。
synchronized原理详解(通俗易懂超级好)
|
存储 Kubernetes 调度
Kubernetes 中存储使用介绍(PV、PVC和StorageClass)
在 Kubernetes 中的应用,都是以 Pod 的形式运行的,当我们要是在 Kubernetes 上运行一些需要存放数据的应用时,便需要关注应用存放的数据是否安全可靠。因为 Pod 是有生命周期的,那么也就是说当 Pod 被删除或重启后,Pod 里面所运行的数据也会随之消失。
3029 0
Kubernetes 中存储使用介绍(PV、PVC和StorageClass)
ly~
|
消息中间件 存储 数据库连接
RocketMQ 消息的重试机制是怎样的?
RocketMQ的消息重试机制确保消息消费失败时能自动重试,直至成功。默认重试16次,时间间隔逐次翻倍,从10秒至数分钟不等。重试在同组内不同消费者间进行,由异常抛出或特定状态返回触发。支持自定义重试次数与时间间隔,建议合理配置避免无限重试,保障系统稳定性和性能。
ly~
4415 2
|
负载均衡 监控 Java
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
32065 8
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础
|
Kubernetes 架构师 Java
史上最全对照表:大厂P6/P7/P8 职业技能 薪资水平 成长路线
40岁老架构师尼恩,专注于帮助读者提升技术能力和职业发展。其读者群中,多位成员成功获得知名互联网企业的面试机会。尼恩不仅提供系统化的面试准备指导,还特别针对谈薪酬环节给予专业建议,助力求职者在与HR谈判时更加自信。此外,尼恩还分享了阿里巴巴的职级体系,作为行业内广泛认可的标准,帮助读者更好地理解各职级的要求和发展路径。通过尼恩的技术圣经系列PDF,如《尼恩Java面试宝典》等,读者可以进一步提升自身技术实力,应对职场挑战。关注“技术自由圈”公众号,获取更多资源。