当前位置: 首页 > news >正文

Spring《二》bean的实例化与生命周期

🍎道阻且长,行则将至。🍓

上一篇:Spring《一》快速入门
下一篇:Spring《三》DI依赖注入


目录

  • 一、bean实例化🍍
    • 1.构造方法 ***
    • 2.静态工厂 *
      • 使用工厂创建对象
      • 实例化bean
    • 3.实例工厂 ***
      • 使用示例工厂创建对象
      • 实例工厂实例化bean
      • FactoryBean
  • 二、生命周期🍑
    • 1.生命周期设置
    • 2.在main方法使用close
    • 3.使用钩子关闭容器


一、bean实例化🍍

在上一篇Spring快速入门👉🏻中,我们使用IOC容器进行对象的创建,在IOC中的对象也称为bean,那么IOC容器是怎么创建bean的呢。

下面介绍bean的实例化方法:构造方法静态工厂实例工厂

1.构造方法 ***

  1. 我们先创建好一个maven项目,在maven配置文件pom中添加spring的依赖,再继续在resources文件夹下new个Spring的配置文件,applicationContext.xml。

  2. 准备好我们的接口和类:BookDaoBookDaoImpl:在接口添加一个save方法,到类中实现,输出一个语句示例。因为要使用构造方法,那我们就写一个无参构造器,并且在里面随便输出一个提示语句。

  3. 写好类之后,我们继续到Spring配置文件中将类配置到容器:<bean id="bookDao" name="book1" class="Demo1.dao.impl.BookDaoImpl"/>,我们可以发现在左侧出现spring的小标志了,表示配置正常;
    在这里插入图片描述

  4. 完成一个运行的程序,若最后可以打印构造器中的内容表示就是创建对象使用了构造函数。

public class AppForInstanceBook {public static void main(String[] args) {ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}

输出:
在这里插入图片描述
并且当构造器为私有的时候,仍然可以访问,说明了Spring的底层使用了反射。回顾参考👉🏻java反射机制
但是Spring只是使用无参构造器。

2.静态工厂 *

使用工厂创建对象

我们可以继续在前面的maven中类似地添加接口和类:OrderDaoOrderDaoImpl,然后在创建一个工厂类:

public class OrderDaoFactory {public static OrderDao getOrderDao(){return new OrderDaoImpl();}
}

完成一个运行的程序,使用工厂获取对象:

public class AppForInstanceOrder {public static void main(String[] args) {//通过静态工厂创建对象OrderDao orderDao = OrderDaoFactory.getOrderDao();orderDao.save();}
}

在这里插入图片描述

实例化bean

要使用静态工厂实例化bean只需要在Spring配置文件中添加<bean id="orderDao" name="Order1" class="Demo1.factory.OrderDaoFactory" factory-method="getOrderDao"/>,注意class是指向工厂类,添加的工厂方法属性指向工厂中创建对象的方法;静态工厂实例化配置成功之后再工厂类中也会有提示:
在这里插入图片描述 👉 在这里插入图片描述
然后在运行方法中从容器获取bean:

ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao orderDao =(OrderDao) ctx.getBean("orderDao");
orderDao.save();

3.实例工厂 ***

使用示例工厂创建对象

我们还是可以继续在前面的maven中类似地添加接口和类:UserDaoUserDaoImpl,再同样的创建一个工厂类:OrderDaoFactory,注意和静态工厂的不一样:

//UserDao
package Demo1.dao;
public interface UserDao {public void save();
}
//UserDaoImpl
package Demo1.dao.impl;
import Demo1.dao.UserDao;
public class UserDaoImpl implements UserDao {@Overridepublic void save() {System.out.println("userDao save...");}
}
//OrderDaoFactory
package Demo1.factory;
import Demo1.dao.UserDao;
import Demo1.dao.impl.UserDaoImpl;
public class UserDaoFactory {public UserDao getUserDao(){return new UserDaoImpl();}
}

我们可以在运行程序中使用实例工厂获取对象:

public class AppForInstanceUser {public static void main(String[] args) {//创建实例工厂对象UserDaoFactory userDaoFactory = new UserDaoFactory();//通过实例工厂对象创建对象UserDao userDao = userDaoFactory.getUserDao();userDao.save();
}

我们想把这种实例工厂也交给Spring:

实例工厂实例化bean

在配置文件中添加:

<bean id="userFactory" class="Demo1.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

在前面的静态工厂中我们只需要配置工厂类进来,使用静态方法就可以获得对象。而这需要先添加工厂,再添加Dao。
我们也可以修改验证一下为什么要这样,当你试图在工厂bean中加实例方法,直接给你报错:
在这里插入图片描述
其实想一想就知道了,这个不是静态方法啊,对象都没有你怎么使用这个方法。
然后在运行程序中添加:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();

在这里插入图片描述

上面的Spring配置还是太麻烦,改!

FactoryBean

Spring为了简化这种配置方式就提供了FactoryBean来简化开发。

创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法:

public class UserDaoFactoryBean implements FactoryBean<UserDao> {@Overridepublic UserDao getObject() throws Exception {return new UserDaoImpl();}@Overridepublic Class<?> getObjectType() {return UserDao.class;}
}

就只需要一个FactoryBean的配置:
<bean id="userDao" class="Demo1.factory.UserDaoFactoryBean"/>

FactoryBean的源代码也不长,我们可以打开看看:

public interface FactoryBean<T> {String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";@NullableT getObject() throws Exception;@NullableClass<?> getObjectType();default boolean isSingleton() {return true;}
}

他提供了3个方法,我们在创建UserDaoFactoryBean的类的时候重写了两个接口的方法:
getObject(),在方法中进行对象的创建并返回;
getObjectType(),返回的是被创建类的Class对象;
isSingleton()就是设置对象是否为单例,默认true。


二、生命周期🍑

生命周期就是从创建到消亡的完整过程。bean的生命周期自然是指bean对象从创建到销毁的过程。

1.生命周期设置

我们想设置:

  • bean创建之后,想要添加内容,比如用来初始化需要用到资源
  • bean销毁之前,想要添加内容,比如用来释放用到的资源
    继续在前面的案例中,我们在实例工厂类添加:
public void init(){System.out.println("init userDaofac...");
}
public void destory(){System.out.println("destory userDaofac...");
}

在bean中追加:init-method="init" destroy-method="destory"
在这里插入图片描述
只有初始化被执行了。问:为什么
Spring的IOC容器是运行在JVM中,运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行。然而main方法执行完后,JVM就退出了,这个时候IOC容器中的bean也就结束了,根本没有调用destroy方法。
所以这个时候我们可以在main方法使用close使用钩子关闭容器

2.在main方法使用close

ApplicationContext 中没有提供close方法,我们需要使用ClassPathXmlApplicationContext
修改

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

就可以使用:ctx.close();了。
在这里插入图片描述

3.使用钩子关闭容器

就是在容器未关闭之前,提前设置好回调函数,让JVM可以在退出之前回调此函数来关闭容器。
就是把前面的ctx.close();换为ctx.registerShutdownHook();

需要修改配置文件还是太麻烦,再改!

前面的方法还是需要在Spring配置文件中添加bean的init-methoddestroy-method,Spring对此进行简化,提供了两个接口来完成生命周期的控制,而不用再进行配置InitializingBeanDisposableBean
在类里面继承接口并重写:

public class UserDaoFactoryBean implements FactoryBean<UserDao> , InitializingBean, DisposableBean {@Overridepublic UserDao getObject() throws Exception {return new UserDaoImpl();}@Overridepublic Class<?> getObjectType() {return UserDao.class;}
//************************@Overridepublic void destroy() throws Exception {System.out.println("destory...");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("ini...");}
}

在运行程序仍然使用ctx.registerShutdownHook();
在这里插入图片描述


回到第一页☝

☕物有本末,事有终始,知所先后。🍭

🍎☝☝☝☝☝我的CSDN☝☝☝☝☝☝🍓

相关文章:

Spring《二》bean的实例化与生命周期

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 上一篇&#xff1a;Spring《一》快速入门 下一篇&#xff1a;Spring《三》DI依赖注入 目录一、bean实例化&#x1f34d;1.构造方法 ***2.静态工厂 *使用工厂创建对象实例化bean3.实例工厂 ***使用示例工厂创建对象实…...

java与kotlin 写法区别

原文链接&#xff1a;https://gitcode.net/mirrors/mindorksopensource/from-java-to-kotlin?utm_sourcecsdn_github_accelerator#assigning-the-null-value Print to Console 打印到控制台 Java System.out.print("Amit Shekhar"); System.out.println("Amit…...

服务器运行深度学习代码使用指南

该内容配置均在九天毕昇下配置。 当前系统使用的linux版本为&#xff1a;Ubuntu 18.04 LTS。 当前版本安装的是&#xff1a;cuda10.1。 九天毕昇平台&#xff1a;https://jiutian.10086.cn/edu/#/home 一、linux下运行python的操作 ls 为列出当前目录中的文件 cd 文件名 进入…...

计算机组成原理 - 2. 数据的表示和运算

整理自天勤高分笔记&#xff0c;购书链接&#xff1a; 24 天勤高分笔记 要记住的几个数字 &#x1f4d3;&#xff1a; 215327682^{15} 3276821532768 216655362^{16} 6553621665536 23121474836482^{31} 21474836482312147483648 23242949672962^{32} 4294967296232429496…...

【js】基础知识点--语句,break和continue,switch,with,for..in,do-while,while

一、break和continue语句&#xff0c;常用 break 语句会立即退出循环&#xff0c;强制继续执行循环后面的语句。而 continue 语句虽然也是立即退出循环&#xff0c;但退出循环后会从循环的顶部继续执行 var num 0; for (var i1; i < 10; i) {if (i % 5 0) {break;}num; …...

【C++】迭代器

内容来自《C Primer&#xff08;第5版&#xff09;》9.2.1 迭代器、9.2.3 begin和end成员、9.3.6 容器操作可能使迭代器失效、10.4.3 反向迭代器 目录 1. 迭代器 1.1 迭代器范围 1.2 使用左闭合范围蕴含的编程假定 2. begin和end成员 3. 容器操作可能使迭代器失效 3.1 编…...

数据可视化在前端中的应用

前端开发中,数据可视化是一种非常重要的技术。它可以将复杂的数据以图形化的方式展示出来,让用户更容易理解和分析数据。在前端中,VUE是一种非常流行的JavaScript框架,可以用来实现各种数据可视化效果。 首先,让我们来看看一些常见的数据可视化方式: 表格:表格是数据可…...

FFmpeg 合并视频文件没声音,不同步原因

查了不少帖子也没搞明白&#xff0c;可能懂的人不会遇到吧。 1 没声音是因为我几个视频文件中&#xff0c;有的没音轨&#xff0c;就是用文字生成了个视频&#xff0c;需要先给它加个dummy的音轨才行。 2 视频不同步是因为各个视频格式不一样&#xff0c;参数挺多我也不知道具…...

绕不开的“定位”

绕开“定位”这个词谈企业战略和品牌 相当于揪住头发离开地球 定位这个词&#xff0c;已经进入商业界的心智中去了 发明这个词的特劳特和里斯的思想有啥差异&#xff1f; 《定位屋》刨析的很到位 趣讲大白话&#xff1a;把握概念的源头&#xff0c;就理解对了大部分 【趣讲信息…...

《Effective Objective-C 2.0 》 阅读笔记 item12

第12条&#xff1a;理解消息转发机制 1. 消息转发机制 当对象接收到无法解读的消息后&#xff0c;就会启动“消息转发”机制&#xff0c;开发者可经由此过程告诉对象应该如何处理未知消息。 消息转发分为两大阶段 第一阶段&#xff1a;先征询接收者所属的类&#xff0c;看其…...

云原生计算能消除技术债务吗?

云原生计算可以将行业领域驱动的设计、GitOps和其他现代软件最佳实践汇总起来&#xff0c;如果企业实施得当&#xff0c;可以减少技术债务。 云原生计算是企业IT的一种新范式&#xff0c;它涉及现代技术的方方面面&#xff0c;从应用程序开发到软件架构&#xff0c;再到保持一…...

9. 回文数

题目 给你一个整数 xxx &#xff0c;如果 xxx 是一个回文整数&#xff0c;返回 truetruetrue &#xff1b;否则&#xff0c;返回 falsefalsefalse 。回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例子 输入&am…...

[SV]SystemVerilog线程之fork...join专题

SystemVerilog线程之fork...join专题 Q&#xff1a;fork-join_none开辟的线程在外部任务退出后也会结束吗&#xff1f; A&#xff1a;后台线程不会结束&#xff0c;任何由fork开辟的线程&#xff08;join、join_any、join_none&#xff09;&#xff0c;无论其外部任务&#xff…...

你看这个spring的aop它又大又宽

aop&#x1f693;AOP 分类AspectJ | 高级但是难用Spring AOP | 易用但仅支持方法aop 原理明月几时有&#xff0c;把酒问青天。——唐代李白《将进酒》 AOP 分类 在 Spring Boot 中&#xff0c;AOP 的实现主要有以下几种&#xff1a; 基于 AspectJ 的 AOP&#xff1a;这是一种基…...

设计模式-创建-单例模式

4.1.1 模式介绍 定义 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一&#xff0c;此模式保证某个类在运行期间&#xff0c;只有一个实例对外提供服务&#xff0c;而这个类被称为单例类。 作用 保证一个类只有一个实例为该实例提供一个全…...

使用mybatis-plus-generator配置一套适合你的CRUD

1、maven引入 mybatis-plus-generator 和模板引擎&#xff0c;你也可以使用freemarker之类的&#xff0c;看个人 <!-- mybatisplus代码生成器 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactI…...

MATLAB实现各种离散概率密度函数(概率密度/分布/逆概率分布函数)

MATLAB实现各种离散概率密度函数(概率密度/分布/逆概率分布函数) 1 常见离散概率分布的基本信息2 常见离散概率分布计算及MATLAB实现2.1 二项分布(Binomial Distribution)2.1.1 常用函数2.2 负二项分布(Negative Binomial Distribution)2.2.1 常用函数2.3 几何分布(Geom…...

指针的基本知识

我们不会用bit去表达一个数据&#xff0c;因为只能放0和1&#xff0c;能表达的数据太少了&#xff0c;内存地址最小单位是字节 11111111 0x0011 1字节8bit,8bit才算作一个地址&#xff0c;地址是以字节为最小单位&#…...

当你的IDE装上GPT

文章目录前言下载安装使用步骤前言 我们可能要从“CV”工程师变成“KL工程师了&#xff0c;为什么叫”KL“工程师呢&#xff0c; 因为只要K和L两个指令就可以直接生成代码、修改代码&#xff0c;哪行代码不会点哪里&#xff0c;他都给你解释得明明白白。 提示&#xff1a;以下…...

一图看懂 pathlib 模块:面向对象的文件系统路径, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 pathlib 模块&#xff1a;面向对象的文件系统路径, 资料整理笔记&#xff08;大全&#xff09;摘要模块图类关系图模块全展开【pathlib】统计常量intbooltuple模块9 fnmatc…...

前端如何将node.js 和mongodb部署到linux服务器上

本文首发自掘金。 记录了我第一次成功部署node.js 和mongodb到linux服务器上了&#xff0c;期间也遇到一些小坑&#xff0c;但是网上各位大佬记录的文章帮了大忙&#xff0c;所以我也将过程记录了下来。 安装Node 使用nvm linux上安装node&#xff0c;肯定首选nvm&#xff…...

mysql数据迁移

背景&#xff1a;随着时间的推移&#xff0c;交易系统中的订单表越来越大&#xff0c;目前达到500w数据。为了防止数据量过大导致的查询性能问题&#xff0c;现将订单表进行拆分&#xff0c;分为实时库和历史库。实时库保留近6个月的数据&#xff0c;用于退款业务需求&#xff…...

【4.3蓝桥备战】小朋友崇拜圈、正则问题

文章目录小朋友崇拜圈正则问题小朋友崇拜圈 小朋友崇拜圈 - 蓝桥云课 (lanqiao.cn) 拿到这道题要先把题目读懂。 下面的一行是表示&#xff1a;编号为i的小朋友&#xff0c;崇拜的对象为编号为path[i]的小朋友。 本题应该使用DFS&#xff0c;深度优先遍历找到可以成环的崇拜圈…...

MySQL读写分离中间件

1.什么是读写分离中间件&#xff1f; 就是实现当[写]的时候转发到主库&#xff0c;当[读]的时候转发到从库的工具。 很类似学习过的proxy,比如nginx proxy做动静分离. 2.为什么要实现读写分离&#xff1f; 1&#xff09;让主库专注于写&#xff0c;因为读可以有很多从库可以干…...

【Spring源码设计模式】单例模式外带设计模式的单例模式

Bean的概念 是Spring框架在运行时管理的对象&#xff0c;是任何引用程序的基本构建块。 Bean的属性 id属性&#xff1a;Bean的唯一标志名&#xff0c;必须以字母开头且不包含特殊字符 class属性&#xff1a;用来定义类的全限定名&#xff08;包名 类名&#xff09; name属性…...

go并发编程 —— singleflight设计模式

什么是singleflight singleflight是一种并发编程设计模式&#xff0c;将同一时刻的多个并发请求合并成一个请求&#xff0c;以减少对下游服务的压力 为什么叫singleflight fly可以理解为请求数&#xff0c;singleflight就是单个请求 使用场景 该模式主要用于防止缓存击穿 …...

【LeetCode】二叉树的中序遍历(递归,迭代,Morris遍历)

目录 题目要求&#xff1a;给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 方法一&#xff1a;递归 方法二&#xff1a;迭代 思路分析&#xff1a; 复杂度分析 代码展示&#xff1a; 方法三&#xff1a;Morris 遍历 思路分析&#xff1a; 复杂度分析…...

银行数字化转型导师坚鹏:数字化转型背景下的银行柜员提升之道

数字化转型背景下的银行柜员提升之道 课程背景&#xff1a; 很多银行都在开展银行数字化运营工作&#xff0c;目前存在以下问题急需解决&#xff1a; l 不清楚银行数字化运营包括哪些关键工作&#xff1f; l 不清楚银行数字化运营工作的核心方法论&#xff1f; l 不清楚银行数字…...

ChatGPT的平替来了?一文总结 ChatGPT 的开源平替,你值得拥有

文章目录【AIGC精选】总结 ChatGPT 的开源平替&#xff0c;你值得拥有1.斯坦福发布 Alpaca 7B&#xff0c;性能匹敌 GPT-3.52.弥补斯坦福 Alpaca 中文短板&#xff0c;中文大模型 BELLE 开源3.国产AI大模型 ChatGLM-6B 开启内测4.中文 Alpaca 模型 Luotuo 开源5. ChatGPT 最强竞…...

关于数据同步工具DataX部署

1.DataX简介 1.1 DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 源码地址&#xff1a;GitHub - alibaba/DataX: DataX是…...