Spring5应用之生命周期

作者简介 :☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页 :Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏
当前专栏 :Spring5应用专栏_Aomsir的博客

基础

什么是生命周期?

对象的生命周期 指的是一个对象创建、存活和消亡的一个完整过程

由于在使用Spring框架以后,我们的对象都交给了Spring进行管理,Spring为我们负责对象的创建、存活、销毁,了解生命周期有利于我们使用好Spring为我们创建的对象

三个阶段

创建阶段

当我们谈及对象的创建阶段,一个核心问题是:Spring工厂何时开始创建这些对象?为了给开发者更多的控制权,Spring工厂引入了scope属性。当我们将其值设为singleton时,对象会在Spring工厂初始化时就被创建 ;而当设置为prototype,对象会在每次调用getBean()方法时重新创建,确保每次获得的都是全新的实例。接下来,我们将通过一个Product类的例子,为您详细解析这两种模式

java 复制代码
public class Product {
    public Product() {
        System.out.println("Product.Product");
    }
}

singleton

  • 开发步骤
    • 配置spring配置文件,为bean设置scope属性为singleton
    • 编写测试类验证猜想
  • 测试结果
    • 第一块是工厂创建,此时没有调用Product类的构造方法
    • 第二块是分隔符
    • 第三块是从工厂中获取对象每次获取的对象引用都是同一个
xml 复制代码
<bean id="product" scope="singleton" class="com.aomsir.basic.life.Product" />
java 复制代码
public class TestSpring {
    @Test
    public void test10() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        System.out.println("-------------------");

        for (int i = 1; i < 3; i++) {
            Product product = ctx.getBean("product", Product.class);
            System.out.println("product = " + product);
        }
    }
}

prototype

  • 开发步骤
    • 配置spring配置文件,为bean设置scope为prototype
    • 编写测试类验证猜想(如上代码)
  • 测试结果
    • 第一块是工厂创建,此时没有调用Product类的构造方法
    • 第二块是分隔符
    • 第三块是从工厂中获取对象,每次获取对象都调用了Product类的构造方法,并且每个对象引用的对象值也不同

注意

可以给bean加上lazy-init懒加载属性,如下给bean加上了singleton和lazy-init属性。对象依旧只会创建一个,但是是在第一次调用的时候创建的

xml 复制代码
<bean id="product" scope="singleton" class="com.aomsir.basic.life.Product" lazy-init="true"/>

初始化阶段

初始化即spring工厂在创建完你所需要创建的对象以后,会调用对象的初始化方法,去进行对应的初始化操作

程序员根据需求提供初始化方法,spring工厂调用这个初始化方法,用于完成初始化操作

初始化方法第一可以实现InitializingBean的afterPropertiesSet()方法、第二种是直接自定义个方法

InitializingBean接口

  • spring为我们提供了InitializingBean接口以及方法,我们按照要求进行开发就行
  • 开发步骤
    • 编写类实现InitializingBean提供的方法
    • 配置spring配置文件
    • 编写测试类进行验证
  • 测试结果
    • 如下测试结果,在调用构造方法创建对象以后,立马就调用了接口实现的方法进行了打印
java 复制代码
public class Product implements InitializingBean {
    public Product() {
        System.out.println("Product.Product");
    }

    /**
     * 这个就是初始化方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("模拟初始化方法被调用");
    }
}
xml 复制代码
<bean id="product" scope="singleton" class="com.aomsir.basic.life.Product"/>
java 复制代码
public class TestSpring {
    @Test
    public void test11() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

自定义方法

  • 上面使用spring提供的接口去实现挺方便的,但后续如果不使用spring框架就会耦合
  • 开发步骤
    • 编写类提供一个方法
    • 配置spring配置文件,init-method属性指定自定义初始化方法
    • 编写测试类进行验证(如上)
  • 测试结果
    • 测试结果跟上面的一致
java 复制代码
public class Product {
    public Product() {
        System.out.println("Product.Product");
    }

    /**
     * 这个就是初始化方法
     */
    public void myInit() {
        System.out.println("模拟初始化方法被调用");
    }
}
xml 复制代码
<bean id="product" scope="singleton" class="com.aomsir.basic.life.Product" init-method="myInit"/>

细节分析

  • 如果一个对象即实现InitializingBean接口又提供自定义初始化方法,则自定义实现方法在后
  • 注入操作一定发生在初始化操作之前
  • 初始化操作是指:数据库、IO、网络的初始化

销毁阶段

销毁阶段指的是spring销毁对象前,会调用对象的销毁方法完成销毁操作

程序员根据需求提供销毁方法,spring工厂调用这个销毁方法,用于完成销毁操作

初始化方法第一可以实现DisposableBean的destroy方法、第二种是直接自定义个方法

DisposableBean接口

  • spring为我们提供了DisposableBean接口以及方法,我们按照要求进行开发就行
  • 开发步骤
    • 编写类实现DisposableBean提供的方法
    • 配置spring配置文件
    • 编写测试类进行验证
  • 测试结果
    • 如下测试结果,在工厂关闭后,立马就调用了接口实现的方法进行了打印
java 复制代码
public class Product implements DisposableBean {
    public Product() {
        System.out.println("Product.Product");
    }


    /**
     * 销毁方法
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("销毁方法被调用");
    }
}
xml 复制代码
<bean id="product" class="com.aomsir.basic.life.Product"/>
java 复制代码
public class TestSpring {
    @Test
    public void test11() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("工厂创建成功");
        ctx.close();
        System.out.println("工厂销毁后");
    }
}

自定义方法

  • 上面使用spring提供的接口去实现挺方便的,但后续如果不使用spring框架就会耦合
  • 开发步骤
    • 编写类提供一个方法
    • 配置spring配置文件,destory-method属性指定自定义初始化方法
    • 编写测试类进行验证(如上)
  • 测试结果
    • 测试结果跟上面的一致
xml 复制代码
<bean id="product" class="com.aomsir.basic.life.Product" destroy-method="myDestroy"/>

细节分析

  • 销毁方法只 适用于scope="singleton"情况下
  • 销毁操作指的是:资源的释放操作、io、connection等

总结

Spring框架的强大之处在于其对对象管理的细致入微。其中,Spring工厂不仅为我们管理了对象的生命周期,还提供了一套完整的机制,确保从对象的创建、初始化,到最后的销毁,每一个步骤都得到妥善处理。这不仅大大简化了开发者的工作,也确保了系统的健壮性和稳定性。通过Spring,开发者可以专注于核心业务逻辑,而无需过多关注底层细节

参考文献

相关推荐
java_nnnn25 分钟前
Spring MVC小案例(1)
java·后端·spring·mvc
陈随易31 分钟前
从今天起,你只需要一个浏览器之Ego lite
前端·后端·程序员
打工仔折腾 AI1 小时前
AI Agent 工程化实战(二):5 分钟跑通 Deep Agent 并逐层拆解底层链路
java·数据库·人工智能·后端·python·langchain·ai agent 实战
学长毕设2 小时前
基于springboot的农资管理系统-附源码
java·spring boot·后端
拖孩2 小时前
一个人 + AI 做的小程序,今天,正式回本了
前端·后端·微信小程序
进击的丸子2 小时前
代理网络环境下 Linux Pro 在线激活实操指南
javascript·后端·安全
念何架构之路3 小时前
Go reflect包值操作 Value 的读写、可设置性与 interface 布局
开发语言·后端·golang
小林ixn3 小时前
用 FastAPI + SQLAlchemy 从零手搓一个博客系统:一套能落地、能讲清楚的 RESTful 后端
后端·python·fastapi
不识君4 小时前
esl-client 2.0.0 发布:Java 项目接入 FreeSWITCH,从引入到使用
spring boot·后端·开源
牧瀬クリスだ4 小时前
Redis五大数据类型全解析:从入门到实战
java·数据库·redis·后端·缓存