如何控制Spring工厂创建对象的次数?详解Spring对象的声明周期!

news2024/11/26 0:45:28

😉😉 学习交流群:

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

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

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

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

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

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

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

    <!--控制这个类的创建的次数,这个参数默认是SingleTon-->
    <bean id="account" class = "com.pactera.spring.scope.Account" scope="singleton"/>
    /*
     * @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识别这个方法通过配置文件来告诉他应该调用哪个。这两种方法可以同时使用,回调会最先执行,初始化方法第二执行

    <bean id = "product" class = "com.pactera.spring.life.Product" init-method ="myInit"/>
    /*
     * @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

    }
    <!---->
    <bean id = "product" class = "com.pactera.spring.life.Product" init-method ="myInit" destroy-method="MyDestroy">
        <property name="name" value="shit"/>

    </bean>

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

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

😉😉 学习交流群:

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

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1265073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

elementui的table合并列,三个一组

<el-table :span-method"objectSpanMethod" :cell-style"iCellStyle" :data"tableData" height"63vh" border style"width: 100%; margin-top: 6px"><el-table-column type"index" label"序号"…

RK3568平台开发系列讲解(Linux系统篇)通过OF函数获取设备树中断信息实验

** 🚀返回专栏总目录 文章目录 一、获取中断资源API详解二、设备树三、驱动程序沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍通过OF函数获取设备树中断信息 。 一、获取中断资源API详解 ① irq_of_parse_and_map 函数 该函数的主要功能是解析设备节点…

Rust UI开发(四):iced中如何添加菜单栏(串口调试助手)

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 这是一个系列博文&#xff0c;本文是第四篇&#xff0c;前三篇链接&#xff1a; 1、Rust UI开发&#xff08;一&#xff09;&#xff1a;使用iced构建UI时…

Doris_Doris导入常见问题

Doris数据导入错误 &#xff1a;the length of input is too larger than schema 可能原因&#xff1a;varchar长度设置过短 Doris表字段乱序 导入palo表中的csv本身无schema信息&#xff0c;csv与palo表字段顺序必须一致&#xff0c;否则会错乱 Doris数据文件中字段比表字段…

linux文件管理命令_切换创建复制移动删除查看修改

1.3 文件管理命令 1.3.1 cd&#xff1a;切换目录&#xff08;change directory&#xff09; cd 绝对路径/相对路径 # 根目录 [rootlocalhost ~]# cd / # 家目录 [rootlocalhost /]# cd [rootlocalhost /]# cd ~ # 父级目录 [rootlocalhost /]# cd .. # 返回上一次目录 [roo…

【vue】v-model在表单元素上的应用

表单元素&#xff1a; https://blog.csdn.net/m0_67930426/article/details/134655644 使用模板 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head><body>&l…

订单管理系统怎么用?有哪些好用的订单管理系统?

订单管理系统怎么用&#xff1f;有哪些好用的订单管理系统&#xff1f;阅读本文你将了解&#xff1a;1、订单管理系统的核心功能&#xff1b;2、订单管理系统的拓展功能&#xff1b;3、订单管理系统推荐。 订单管理系统在当今商业环境中扮演着至关重要的角色。它是企业内部运营…

Flink-执行拓扑图与作业调度

算子与作业提交 一、Flink执行模式1.流执行模式2.批执行模式 二、Flink拓扑图1.基本概念2.拓扑图生成过程 三、拓扑生成和优化1.应用程序2.逻辑视图3.算子链4.Task Slots 四、作业调度1.调度2.拓扑图数据结构3.Job状态转化4.Task状态转化 总结参考链接 一、Flink执行模式 Flin…

文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《基于深度强化学习的城市配电网多级动态重构优化运行方法》

这个标题涉及到城市配电网&#xff08;Urban Power Distribution Network&#xff09;的优化运行方法&#xff0c;其中使用了深度强化学习&#xff08;Deep Reinforcement Learning&#xff09;技术&#xff0c;并且特别强调了多级动态重构。 解读每个关键部分&#xff1a; 基…

Docker 概述与安装

文章目录 1. Docker简介2. 传统虚拟机和容器3. Docker运行速度快的原因4. Docker软件4.1 Docker镜像4.2 Docker容器4.3 Docker仓库 5. Docker架构6. CentOS安装Docker6.1 卸载旧版本6.2 配置yum资源库6.3 安装Docker引擎6.4 启动docker引擎6.5 设置开机自启 7. 卸载Docker8. 运…

【C++初阶】五、类和对象(日期类的完善、流运算符重载函数、const成员、“”取地址运算符重载)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【C初阶】四、类和对象 &#xff08;构造函数、析构函数、拷贝构造函数、赋值运算符重载函数&#xff09;-CSDN博客 一 . 日期类的完善 此次日期类的成员函数&#xff0c;采用声明…

Flink Flink中的合流

一、Flink中的基本合流操作 在实际应用中&#xff0c;我们经常会遇到来源不同的多条流&#xff0c;需要将它们的数据进行联合处理。所以 Flink 中合流的操作会更加普遍&#xff0c;对应的 API 也更加丰富。 二、联合&#xff08;Union&#xff09; 最简单的合流操作&#xf…

EZDML基本介绍

一、表结构设计器(EZDML) 这是一个数据库建表的小软件&#xff0c;可快速的进行数据库表结构设计&#xff0c;建立数据模型。类似大家常用的数据库建模工具如PowerDesigner、ERWIN、ER-Studio和Rational-Rose等的超级精简版。 官方下载地址&#xff1a;http://www.ezdml.com/d…

解析javascript数组方法 find 和 filter 有何区别

首先用一个案例可以很直观的看到 find 和 filter 的区别&#xff1b; 相同点&#xff1a; 两者分别可以接受三个参数&#xff1a;当前元素、当前索引、整个数组&#xff1b;两者都可以用来查找数组中符合条件的元素&#xff1b; 不同点&#xff1a; find&#xff1a; 用于查…

docker镜像管理命令

镜像管理命令 docker build : 命令用于使用 Dockerfile 创建镜像 docker build [OPTIONS] PATH | URL | - OPTIONS说明&#xff1a; --add-host :向hosts文件中添加自定义 host:ip 映射 --build-arg[] :设置镜像创建时的变量&#xff1b; --cache-from :指定镜像用作当前构建…

华为ospf和isis双点双向路由重分布的次优路径和环路终极解决方案

r5上直接导入直连路由 r3和r2进行双点双向路由重分布 查看R3去往R5产生了次优路径&#xff1a; 因为是R2先互相引入的isis和ospf&#xff0c;所以R3会产生次优路径&#xff0c;如果是R3先相互引入ospf和isis&#xff0c;那就是R2去R5会产生次优路径&#xff0c;而R3本身不会。…

华为设备使用python实现文件自动保存下载

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址为172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;STELNET实现设备的自动保存配置文件&#xff0c;使用SFTP实现设备的文件下载。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1…

Spark---资源、任务调度

一、Spark资源调度源码 1、Spark资源调度源码过程 Spark资源调度源码是在Driver启动之后注册Application完成后开始的。Spark资源调度主要就是Spark集群如何给当前提交的Spark application在Worker资源节点上划分资源。Spark资源调度源码在Master.scala类中的schedule()中进行…

揭开 BFC 的神秘面纱:前端开发必知必会

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【多线程】-- 05 Lambda表达式

多线程 4 Lambda表达式 λ是希腊字母表中排序第十一位的字母&#xff0c;英语名称为Lambda是为了避免匿名内部类定义过多实质属于函数式编程的概念 为什么要使用Lambda表达式&#xff1f; 避免匿名内部类定义过多可以让代码看起来很简洁去掉了一堆没有意义的代码&#xff0…