Spring:IOC的详解☞Bean的实例化、Bean的生命周期

1、Bean基础配置

bean的基础配置:

<bean id="" class=""/>

Bean的别名:name属性

Bean的作用范围:scope配置

使用bean的scope属性可以控制bean的创建是否为单例:

  • singleton 默认为单例
  • prototype 为非单例

——单例模式下多次从容器中获取bean的地址是是一样的。

——多例模式下多次从容器中获取bean的地址是不一样的。也就是创建了多个不同的实例。

public class AppForScope {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao1 = (BookDao) ctx.getBean("bookDao");BookDao bookDao2 = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao1);System.out.println(bookDao2);}
}
  • 为什么bean默认为单例?
    • bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
    • bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
  • bean在容器中是单例的,会不会产生线程安全问题?
    • 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,
    • 因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
    • 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,
    • 因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。
  • 哪些bean对象适合交给容器进行管理?
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  • 哪些bean对象不适合交给容器进行管理?
    • 封装实例的域对象,因为会引发线程安全问题,所以不适合。
<beanid="bean的唯一标识"class="bean的类别名"scope="bean的作用范围,有singleton、prototype"name="为bean的别名">

2、Bean实例化

bean本质上就是对象,创建bean使用构造方法。

构造方法无论是共有还是私有 都会被sping容器获取::spring通过反射获取类

Bean实例化的三种方式:

  1. 使用类中的构造方法进行创建,如果添加参数就不能运行了
  2. 静态工厂(了解):在bean标签中添加属性=工厂类中创建类的方法
  3. 使用实例工场(了解):使用了两个Bean标签
  4. 实例工厂的加强(实用):使用FactoryBean实例化bean

(1)bean是如何创建的呢?

        构造方法

(2)Spring的IOC实例化对象的三种方式分别是:

  • 构造方法(常用)
  • 静态工厂(了解)
  • 实例工厂(了解)
    • FactoryBean(实用)

这些方式中,重点掌握构造方法和FactoryBean即可。

需要注意的一点是,构造方法在类中默认会提供,但是如果重写了构造方法,默认的就会消失,在使用的过程中需要注意,如果需要重写构造方法,最好把默认的构造方法也重写下。

3、Bean生命周期

关于bean的相关知识还有最后一个是bean的生命周期,对于生命周期,我们主要围绕着bean生命周期控制来阐述:

  • 首先理解下什么是生命周期?
    • 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。
  • bean生命周期是什么?
    • bean对象从创建到销毁的整体过程。
  • bean生命周期控制是什么?
    • 在bean创建后到销毁前做一些事情。

现在我们面临的问题是如何在bean的创建之后和销毁之前把我们需要添加的内容添加进去。

设置生命周期:

添加生命周期的控制方法,具体的控制有两个阶段:

  • bean创建之后,想要添加内容,比如用来初始化需要用到资源
  • bean销毁之前,想要添加内容,比如用来释放用到的资源

步骤1:添加初始化和销毁方法

针对这两个阶段,我们在BooDaoImpl类中分别添加两个方法,==方法名任意==

public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}//表示bean初始化对应的操作public void init(){System.out.println("init...");}//表示bean销毁前对应的操作public void destory(){System.out.println("destory...");}
}

步骤2:配置生命周期

在配置文件添加配置,如下:

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

步骤3:运行程序

运行AppForLifeCycle打印结果为:

从结果中可以看出,init方法执行了,但是destroy方法却未执行,这是为什么呢?

  • Spring的IOC容器是运行在JVM中
  • 运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行
  • main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了
  • 所以没有调用对应的destroy方法

知道了出现问题的原因,具体该如何解决呢?

close关闭容器

  • ApplicationContext中没有close方法
  • 需要将ApplicationContext更换成ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 调用ctx的close()方法
ctx.close();
  • 运行程序,就能执行destroy方法的内容

注册钩子关闭容器

  • 在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
  • 调用ctx的registerShutdownHook()方法
ctx.registerShutdownHook();

注意:registerShutdownHook在ApplicationContext中也没有

  • 相同点:这两种都能用来关闭容器
  • 不同点:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。

实现接口来完成生命周期设置

Spring提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置init-method和destroy-method

接下来在BookServiceImpl完成这两个接口的使用:

修改BookServiceImpl类,添加两个接口InitializingBean, DisposableBean并实现接口中的两个方法afterPropertiesSet和destroy

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save(); }public void destroy() throws Exception {System.out.println("service destroy");}public void afterPropertiesSet() throws Exception {System.out.println("service init");}
}

bean生命周期小结

(1)关于Spring中对bean生命周期控制提供了两种方式:

  • 在配置文件中的bean标签中添加

init-method和destroy-method属性

  • 类实现

InitializingBean与DisposableBean接口,这种方式了解下即可。

(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:

  • 初始化容器
    • 1.创建对象(内存分配)
    • 2.执行构造方法
    • 3.执行属性注入(set操作)
    • 4.执行bean初始化方法
  • 使用bean
    • 1.执行业务操作
  • 关闭/销毁容器
    • 1.执行bean销毁方法

(3)关闭容器的两种方式:

  • ConfigurableApplicationContext是ApplicationContext的子类
    • close()方法
    • registerShutdownHook()方法

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES6 (一)——ES6 简介及环境搭建

目录 简介 环境搭建 可以在 Node.js 环境中运行 ES6 webpack 入口 (entry) loader 插件 (plugins) 利用 webpack 搭建应用 gulp 如何使用&#xff1f; 简介 ES6&#xff0c; 全称 ECMAScript 6.0 &#xff0c;是 JavaScript 的下一个版本标准&#xff0c;2015.06 发版…

Python 如何创建和解析 XML 文件

XML&#xff08;可扩展标记语言&#xff09;是一种广泛使用的标记语言&#xff0c;主要用于存储和传输数据。它具有结构化、层次化的特点&#xff0c;常被用作数据交换格式。Python 提供了多种工具和库来处理 XML 文件&#xff0c;包括创建、解析和操作 XML 文档。 一、XML 简…

Ubuntu24.04使用SRS 搭建 RTMP流媒体服务器

一、简介 SRS(Simple Realtime Server)是一个简单高效的实时视频服务器&#xff0c; 是国人写的一款非常优秀的开源流媒体服务器软件&#xff0c;可用于直播/录播/视频客服等多种场景&#xff0c;其定位是运营级的互联网直播服务器集群。支持RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28…

手撕C++入门基础

1.C介绍 C课程包括&#xff1a;C语法、STL、高阶数据结构 C参考文档&#xff1a;Reference - C Reference C 参考手册 - cppreference.com cppreference.com C兼容之前学习的C语言 2.C的第一个程序 打印hello world #define _CRT_SECURE_NO_WARNINGS 1 // test.cpp // …

甄选系列“论软件开发过程RUP及其应用”,软考高级论文,系统架构设计师论文

论文真题 RUP(Rational Unified Process)是IBM公司的一款软件开发过程产品,它提出了一整套以UML为基础的开发准则,用以指导软件开发人员以UML为基础进行软件开发。RUP汲取了各种面向对象分析与设计方法的精华,提供了一个普遍的软件过程框架,可以适应不同的软件系统、应用…

http request-02-Ajax XHR 的替代方案-fetch 标准

http 请求系列 http request-01-XMLHttpRequest XHR 简单介绍 http request-01-XMLHttpRequest XHR 标准 Ajax 详解-01-AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;入门介绍 Ajax XHR 的替代方案-fetch Ajax XHR 的替代方案-fetch 标准 Ajax 的替代方案…

06、stm32 引脚输入

一、配置 二、代码 /* USER CODE BEGIN WHILE */while (1){/** 引脚默认上拉 高电平 按键按下 读取到低电平* */if(HAL_GPIO_ReadPin(GPIOB,KEY_Pin) GPIO_PIN_RESET ){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOB,KEY_Pin) GPIO_PIN_RESET ){HAL_GPIO_TogglePin(GPIOC,LED_P…

【C++】智能指针详解

一、从new和delete谈起 在C中&#xff0c;可以使用new和delete关键字进行对象的创建和销毁&#xff0c;new一个对象实际上是在堆上分配内存&#xff0c;而new出来的对象也要自己用delete释放&#xff0c;从而回收内存&#xff0c;否则会造成内存的泄露。由程序员自己new来分配…

修改mf后缀的文件为zip(仅修改文件后缀,并非通过压缩解压的方式修改实际的文件)

仅修改文件后缀的python实现 1、以下代码仅简单的修改mf后缀的文件为zip&#xff0c;并非通过压缩解压的方式修改实际的文件。 2、执行后原有mf后缀的文件直接转换为zip的后缀&#xff0c;请注意备份。 &#xff08;注意&#xff1a;如果rar或者tar转成zip&#xff0c;请使用解…

机器学习/自主系统与亚当·斯密

人工智能中的机器学习和自主系统是当前科技领域的热门话题&#xff0c;它们与亚当斯密的经济学理论之间可能存在一些潜在的联系和启示。亚当斯密的经济学理论主要关注市场经济的运行和资源分配。他的核心观点是&#xff0c;通过市场机制的作用&#xff0c;个体追求自身利益的行…

前端框架(三件套)

学习网站 HTML 系列教程&#xff08;有广告&#xff09; HTML&#xff08;超文本标记语言&#xff09; | MDN (mozilla.org)&#xff08;英文不太友好&#xff09; 1.HTML5 & CSS3 1.1HTML5表格 <!DOCTYPE html> <html lang"en"> <head>…

李宏毅 机器学习与深度学习【2022版】 01

文章目录 一、基本概念二、深度学习内容总览三、预测YouTube播放量的模型1、假设一个含有未知参数的函数式2、根据Training Data定义一个 Loss3、最优化Optimization4、测试集验证模型性能5、线性模型特征维度提升6、非线性模型7、ReLU 四、深度学习概述1、Fully Connect Feedf…

边缘计算技术解决行业痛点,TSINGSEE智能分析网关V4技术特点与应用场景解析

一、行业背景 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;边缘计算硬件作为其核心组成部分&#xff0c;正逐步成为市场的新宠。这些硬件不仅提升了数据处理和分析的效率&#xff0c;还极大地降低了数据传输的延迟&#xff0c;为各行各业的智能化转型提…

Unity | 游戏开发中的优化思维

目录 ​​​​​​一、优化三板斧&#xff1a; 第1步&#xff1a;定标准 第2步&#xff1a;重数据 第3步&#xff1a;严测试 二、流程和性能的优化 1.定标准&#xff1a; 2.重数据&#xff1a; 三、交互和表现的优化 1.卡顿和延迟 2.手感硬 四、沟通和学习 ​​​​…

string模拟

本章准备对string模拟进行讲解&#xff0c;以下是string的学习网址&#xff1a; string - C Reference (cplusplus.com) string本质可以理解为储存char类型的顺序表&#xff0c;其中string的迭代器用一个char*就可以解决。所以string类成员变量如下&#xff1a; 这里用了一个命…

普通人如何抓住AI这个风口?

最强AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频百万播放量https://aitools.jurilu.com/ AI不仅仅是提升办公效率的利器&#xff0c;更是普通人目前最容易上手和变现的工具&#xff01;对于风口&#xff0c;大家应该都听…

使用yolov5实现目标检测简单案例(测试图片)

一、前置 测试这个案例之前需要安装一些前置的东西&#xff0c;如果已经安装的可以忽略&#xff0c;下面我给出我跟着做的一些很好的博客提供大家参考&#xff0c;因为我们主要目的还是实现yolov5的目标检测。 1、安装nvidia显卡驱动 可以参考&#xff1a;【Windows】安装NV…

Unified 阻抗控制 architecture、framework、approach

Unified 阻抗控制&#xff08;Unified Impedance Control&#xff09;作为一种控制策略&#xff0c;其architecture&#xff08;架构&#xff09;、framework&#xff08;框架&#xff09;和approach&#xff08;方法&#xff09;为&#xff1a; 一、Unified 阻抗控制 Archite…

京东数据编织

计算引擎是Hbase 中间计算结果的物化【就是存下来】 自动物化 在这里插入图片描述

Python自动化:解锁高效工作与生产力的密钥

在当今快节奏的数字时代&#xff0c;自动化已成为提升工作效率、优化流程、减少人为错误的不可或缺的工具。Python&#xff0c;作为一种功能强大、易于学习且应用广泛的编程语言&#xff0c;在自动化领域扮演着举足轻重的角色。无论是数据处理、Web自动化、软件测试&#xff0c…