如何控制Spring工厂创建对象的次数?详解Spring对象的生命周期!
作者:mmseoamin日期:2023-12-05

如何控制Spring工厂创建对象的次数?详解Spring对象的生命周期!,第1张

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

一:如何控制Spring工厂创建对象的次数

1:控制简单对象的创建次数

    
    
    /*
     * @Description:测试spring只创建一个对象。
     * @Author: DaShu
     * @Date: 2021/5/31 14:31
     */
    @Test
    public void test18(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Account account = (Account)ctx.getBean("account");
        Account account1 = (Account) ctx.getBean("account");
        System.out.println(account == account1);
        //当是singleton的时候,spring只会创建一次这个对象。
        //当是prototype的时候,获取一次创建一次。
        //spring当中不写这个属性的时候,默认就是singleton。
    }

2:控制复杂对象的创建次数

        FactoryBean接口当中的isSingleTon()重写的时候,return true即可。

        实例工厂和静态工厂,还是以scope属性的方式进行控制。

3:为什么控制创建对象的次数

        有些对象是可以大家公用的,可以公用的这些对象就创建一次就可以了,有些对象是不能公用的,不能公用的就一人创建一次,这样做就是节省内存的空间,节省不必要的内存浪费

4:什么样的对象只创建一次就行了

        SqlSessionFactory这个mybatis工厂对象是一个重量级的对象,重量级的对象只创建一次就好了,Dao,的对象,Service只创建一次被大家公用就可以了

5:什么样的对象每次都创建新的呢

        1:connection对象,设计到事务.

        2:sqlSession对象,封装了连接对象。

        3:Session对象。 Struct2当中Controller当中的actrion

总结:线程安全,可以公用,才只创建一次

二:对象的生命周期

1:什么是对象的生命周期

        对象的生命周期指的是一个对象创建到销毁的完整的过程。

2:研究对象生命周期的意义

        User user = new User();我们通过new的方式在java虚拟机当中创建了一个对象,只要有引用指向这个对象,对象就会一直存在于jvm内存当中,当虚拟机内存满了,或者整个进程结束了,那么这个对象就消亡了。

        对象交由Spring进行创建和管理之后,对象的创建、存活(保存)、销毁都交由Spring进行管理,我们需要了解其中的原理,并且合理的进行利用。

3:声明周期三阶段

        对象交由Spring创建之后,生命周期的三个阶段

(一):创建阶段

        Spring工厂创建对象,当对象的创建是scope = singleton的时候,spring工厂创建的同时,对象也就被创建了,当对象的创建是scope = prototype的时候,spring会在获取对象的同时创建对象。获取对象就是getBean()方法执行的时候

        如果scope是 singleton但是我们就想在getBean()的时候获取对象,实现一种懒加载的情况,那么我们应该怎么做?添加一个lazy-init= true属性

        总结:singleton情况默认是在工厂对象创建的时候就创建了,如果这个singleton类型想要做到懒加载的话,bean标签当中添加一个属性就好了,单例默认都不是懒加载,多例默认都是懒加载,如果想改变这个规则,可以添加一个属性。

(二):初始化阶段

        初始化阶段:Spring工厂创建完对象之后会调用对象的初始化方法完成对应的初始化操作。

        初始化方法是谁提供:是由程序员根据需求,提供初始化方法,完成初始化操作。

        初始化方法调用:Spring的工厂来调用初始化方法

        初始化方法的定义:Spring为我们提供了两种定义对象初始化方法的途径,第一种是类实现InitializingBean这个接口,在这个接口当中为我们定义了一个方法,afterPropertiesSet()方法。可以把我们对象的初始化代码写到这里边,当Spring识别类实现了这个接口之后,就会调用这个方法(这个接口耦合了Spring的接口,造成了一定的侵入)。第二种方式不需要我们实现任何接口,在对象中提供一个普通的方法,这个方法 public void myInit(){} 方法名可以任意取,spring识别这个方法通过配置文件来告诉他应该调用哪个。这两种方法可以同时使用,回调会最先执行,初始化方法第二执行

    
    /*
     * @Description:测试--afterPropertiesSet方法执行了 spring的初始化方法
     * @Author: DaShu
     * @Date: 2021/5/31 14:31
     * result:
     */
    @Test
    public void test20(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        System.out.println("-----------------------工厂对象已经加载完毕------------------------");
        Product product = (Product) ctx.getBean("product");
        //Product.Product
        //afterPropertiesSet方法执行了。
        //myInit方法执行了。
    }

        如果一个对象上上述两种方式都采用了,那么会怎么样?

        先执行实现接口执行回调的方法,在执行普通的初始化方法。

        Spring创建完对象之后会进行DI注入和初始化那么spring是先进行注入还是先进行初始化呢

        Spring创建对象之后会先进行注入,注入完成之后在进行初始化。也就是先为成员边变量赋值,在进行初始化,所以,初始化方法叫做afterpropertyset,初始化方法经常用作资源的加载或者资源的初始化。

        //Product.Product  --构造方法创建对象
        //Product.setName  --set方法进行注入
        //afterPropertiesSet方法执行了。--接口方法进行初始话
        //myInit方法执行了。--普通方法进行初始化。

        什么叫做初始化操作?

        对于数据的初始化: 数据库--    IO---网络。所谓的初始化操作大多是资源的初始化,大部分情况下都是为了系统资源的初始化,这些操作会耗费时间占用内存资源,所以我们一般在系统启动的时候进行操作。

(三):销毁阶段

        什么叫做销毁阶段?

        Spring销毁对象前会调用spring的销毁方法完成销毁操作

        Spring什么时候销毁他所创建的对象呢

        Spring 销毁他创建的对象,是在工厂关闭的时候,在工厂关闭之前也就是调用close方法的时候,spring工厂会销毁他所创建的对象

        销毁方法是谁定义的

        销毁方法是程序员定义的,程序员是根据需求完成销毁操作

        销毁方法谁来调用呢

        Spring来调用,Spring工厂来完成调用

        如何定义销毁方法

        定义销毁方法也有两种方式,第一种方法是实现spring的DisposableBean接口,通过实现其中方法进行销毁

        另外一种就是通过标签的方式指定方法的名称。自定义一个普通的销毁方法。所谓的销毁操作就是资源释放的操作

    /*
     * @Description:测试--destroy()方法
     * @Author: DaShu
     * @Date: 2021/5/31 14:31
     * result:
     */
    @Test
    public void test21(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Product product = ctx.getBean("product", Product.class);
        ((ClassPathXmlApplicationContext)ctx).close();
        //Product.Product
        //Product.setName
        //afterPropertiesSet方法执行了。
        //myInit方法执行了。
        //2021-06-02 15:11:03 DEBUG ClassPathXmlApplicationContext:987 - Closing org.springframework.context.support.ClassPathXmlApplicationContext@5e4c8041, started on Wed Jun 02 15:11:02 CST 2021
        //Product.destroy
        //Product.MyDestroy
    }
    
    
        
    

        销毁细节分析

        销毁细节操作只适用于scope为singleton的作用,对于另外一种没有任何作用

        什么叫做销毁操作

        所谓的销毁操作值得一些资源的释放,比方说:io流的关闭,链接的关闭。这种销毁操作用的很少。

如何控制Spring工厂创建对象的次数?详解Spring对象的生命周期!,第2张

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞