Spring的生命周期及Spring Bean单例和多例---超详细教学

一,何为spring生命周期    

    一个Bean对象从被Spring容器创建到被销毁的整个过程。Spring框架对Bean对象的生命周期进行了管理,提供了灵活性和控制权,让开发人员能够在不同的阶段进行自定义操作

1.1生命周期图

1.2.为什么要学习对象的生命周期?

1.2.1 定位和解决问题

     对象的生命周期可以帮助我们准确定位和解决程序中的问题。当程序出现 bug 或异常时,了解对象的生命周期可以帮助我们追踪问题所在,并在适当的阶段进行调试和修复。

1.2.2 资源管理

    对象的生命周期涉及到资源的分配和释放,如内存、数据库连接、文件等。了解对象的生命周期可以帮助我们更好地管理和优化资源的使用,避免资源泄漏或过度占用资源的情况发生。

1.2.3 性能优化

   了解对象的生命周期可以帮助我们优化程序的性能。通过有效地管理对象的创建和销毁,以及合理利用对象池、缓存等技术,可以减少不必要的资源消耗和提高程序的运行效率。

1.2.4 设计模式和架构

   对象的生命周期与设计模式和架构密切相关。学习对象的生命周期可以帮助我们更好地设计和实现面向对象的系统,选择合适的设计模式和架构来管理和组织对象,以实现可维护、可扩展和高效的系统

1.2.5 对象的状态管理

     对象的生命周期涉及到对象的状态转换和行为变化。了解对象的生命周期可以帮助我们更好地管理对象的状态,避免状态混乱或不一致的情况发生,以确保程序的正确性和可靠性

 1.3 生命周期大致流程

1. Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化


2. Bean实例化后将Bean的引入和值注入到Bean的属性中


3. 如果Bean实现了BeanNameAware接口的话,Spring将Bean的id传递给setBeanName()方法
BeanNameAware的作用:让Bean获取自己在BeanFactory配置中的名字。


4. 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
BeanFactoryAware的作用:让Bean获取配置他们的BeanFactory的引用。


5. 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入
为什么使用ApplicationContextAware接口:在spring项目中,类之间的关系是spring容器来管理的,但是一个项目中有些类不受spring容器管理缺需要使用受spring管理的bean,这时候不能通过正常的方式注入bean,这时候spring给我们提供了ApplicationContextAware接口,我们可以编写一个工具类来实现ApplicationContextAware,通过工具类来获取我们需要的bean然后供不在spring容器中的类调用。


6. 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法
postProcessBeforeInitialization()方法:初始化方法之前调用


7. 如果Bean实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
afterPropertiesSet()方法:初始化方法。如果使用了init-method声明了初始化方法,则执行顺序为:先执行afterPropertiesSet()方法,再执行init-method声明的方法。


8. 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法
postProcessAfterInitialization()方法:初始化方法之后调用


9. 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁


10. 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用
destory()方法:销毁前调用。如果使用了destory-method声明了销毁方法,则执行顺序为:先执行destory()方法,再执行destory-method声明的方法。

二, Spring Bean的单例与多例的作用域

2.1 单例模式(Singleton):

  • 单例是指在整个应用程序上下文中只创建一个实例,并且所有的请求都会返回同一个实例
  • 默认情况下,Spring容器中的Bean都是单例的
  • 单例模式适用于那些不需要维护状态的Bean,或者对资源消耗较大的Bean进行共享

缺点:使用单例会有变量污染,单例是根据spring上下文初始化;容器生对象生,容器死对象死

2.2 多例模式(Prototype):

  • 多例是指每次请求时都会创建一个新的实例,每个实例都是独立的
  • 每次从容器中获取该Bean时,都会创建一个新的实例
  • 多例模式适用于那些需要维护状态的Bean,或者对资源消耗较小的Bean进行独立创建

缺点:使用多例及其消耗内存,多例使用时候才会创建,销毁跟着jvm走。

三  单例Bean与多例Bean的配置方式(两种)

3.1 注解方式:

// 使用注解配置单例Bean
@Component
@Scope("singleton")
public class MySingletonBean {
    // ...
}

// 使用注解配置多例Bean
@Component
@Scope("prototype")
public class MyPrototypeBean {
    // ...
}

3.2  XML方式:

<!-- 使用XML配置单例Bean -->
    <bean id="paramAction" class="com.zking.beanlife.ParamAction" scope="singleton">
    <!-- ... -->
</bean>

<!-- 使用XML配置多例Bean -->
  <bean id="paramAction" class="com.zking.beanlife.ParamAction" scope="prototype">
    <!-- ... -->
</bean>

单例案例:

定义一个类,并创建三个方法

package com.zking.beanlife;

public class InstanceFactory {
	public void init() {
		System.out.println("初始化方法");
	}

	public void destroy() {
		System.out.println("销毁方法");
	}

	public void service() {
		System.out.println("业务方法");
	}
}

后端Servlet

package com.zking.beanlife;

import java.util.List;

public class ParamAction {
	private int age;
	private String name;
	private List<String> hobby;
	private int num = 1;
	// private UserBiz userBiz = new UserBizImpl1();

	public ParamAction() {
		super();
	}

	public ParamAction(int age, String name, List<String> hobby) {
		super();
		this.age = age;
		this.name = name;
		this.hobby = hobby;
	}

	public void execute() {
		// userBiz.upload();
		// userBiz = new UserBizImpl2();
		System.out.println("this.num=" + this.num++);
		System.out.println(this.name);
		System.out.println(this.age);
		System.out.println(this.hobby);
	}
}

 

测试类:

package com.zking.beanlife;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/*
 * spring	bean的生命週期
 * spring	bean的單例多例
 */
public class Demo2 {
	// 体现单例与多例的区别
	@Test
	public void test1() {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
//		InstanceFactory   instanceFactory = (InstanceFactory) applicationContext.getBean("instanceFactory");
		//		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
		ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
		ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
//		 System.out.println(p1==p2);
		p1.execute();
		p2.execute();
		
//		单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
		applicationContext.close();
	}

	// 体现单例与多例的初始化的时间点 instanceFactory
	@Test
	public void test2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
	}

	// BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式
	// 默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化
	@Test
	public void test3() {
		// ClassPathXmlApplicationContext applicationContext = new
		// ClassPathXmlApplicationContext("/spring-context.xml");

		Resource resource = new ClassPathResource("/spring-context.xml");
		BeanFactory beanFactory = new XmlBeanFactory(resource);
//		InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
		
	}

}

spring Config文件的配置

 

运行结果:

 

这里的num值分别为1和2,则说明是单例的,单例模式即存在变量污染

多例案例:

 

运行结果:

 多例使用时候才会创建,销毁跟着jvm走

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch训练深度卷积生成对抗网络DCGAN

文章目录 DCGAN介绍代码结果参考 DCGAN介绍 将CNN和GAN结合起来&#xff0c;把监督学习和无监督学习结合起来。具体解释可以参见 深度卷积对抗生成网络(DCGAN) DCGAN的生成器结构&#xff1a; 图片来源&#xff1a;https://arxiv.org/abs/1511.06434 代码 model.py impor…

Docker容器:docker的资源控制及docker数据管理

文章目录 一.docker的资源控制1.CPU 资源控制1.1 资源控制工具1.2 cgroups有四大功能1.3 设置CPU使用率上限1.4 进行CPU压力测试1.5 设置50%的比例分配CPU使用时间上限1.6 设置CPU资源占用比&#xff08;设置多个容器时才有效&#xff09;1.6.1 两个容器测试cpu1.6.2 设置容器绑…

马上七夕到了,用各种编程语言实现10种浪漫表白方式

目录 1. 直接表白&#xff1a;2. 七夕节表白&#xff1a;3. 猜心游戏&#xff1a;4. 浪漫诗句&#xff1a;5. 爱的方程式&#xff1a;6. 爱心Python&#xff1a;7. 心形图案JavaScript 代码&#xff1a;8. 心形并显示表白信息HTML 页面&#xff1a;9. Java七夕快乐&#xff1a;…

【学习笔记之vue】These dependencies were not found:

These dependencies were not found:方案一 全部安装一遍 我们先浅试一个axios >> npm install axios 安装完报错就没有axios了&#xff0c;验证咱们的想法没有问题&#xff0c;实行&#xff01; ok

city walk结合VR全景,打造新时代下的智慧城市

近期爆火的city walk是什么梗&#xff1f;它其实是近年来备受追捧的城市漫步方式&#xff0c;一种全新的城市探索方式&#xff0c;与传统的旅游观光不同&#xff0c;城市漫步更注重与城市的亲密接触&#xff0c;一步步地感受城市的脉动。其实也是一种自由、休闲的方式&#xff…

【Windows系统编程】03.远线程注入ShellCode

shellcode&#xff1a;本质上也是一段普通的代码&#xff0c;只不过特殊的编程手法&#xff0c;可以在任意环境下&#xff0c;不依赖于原有的依赖库执行。 远程线程 #include <iostream> #include <windows.h> #include <TlHelp32.h>int main(){HANDLE hPr…

stable diffusion基础

整合包下载&#xff1a;秋叶大佬 【AI绘画8月最新】Stable Diffusion整合包v4.2发布&#xff01; 参照&#xff1a;基础04】目前全网最贴心的Lora基础知识教程&#xff01; VAE 作用&#xff1a;滤镜微调 VAE下载地址&#xff1a;C站&#xff08;https://civitai.com/models…

小程序的数据绑定和事件绑定

小程序的数据绑定 1.需要渲染的数据放在index.js中的data里 Page({data: {info:HELLO WORLD,imgSrc:/images/1.jpg,randomNum:Math.random()*10,randomNum1:Math.random().toFixed(2)}, }) 2.在WXML中通过{{}}获取数据 <view>{{info}}</view><image src"{{…

爬虫逆向实战(二)--某某观察城市排行榜

一、数据接口分析 主页地址&#xff1a;某某观察 1、抓包 通过抓包可以发现数据接口是multi 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无cookie是否加密&#xff1f; 无响应数据是否加密&#xff1f; 通过查看“响应”板块可以…

windows10 安装WSL2, Ubuntu,docker

AI- 通过docker开发调试部署ChatLLM 阅读时长&#xff1a;10分钟 本文内容&#xff1a; window上安装ubuntu虚拟机&#xff0c;并在虚拟机中安装docker&#xff0c;通过docker部署数字人模型&#xff0c;通过vscode链接到虚拟机进行开发调试.调试完成后&#xff0c;直接部署在云…

如何搭建游戏服务器?有哪些操作步骤

​  选择游戏服务器提供商 为确保游戏服务器的稳定运行和及时响应问题&#xff0c;选择一个正规、靠谱的游戏服务器提供商非常重要。 选择服务器操作系统 根据不同游戏的需求&#xff0c;选择适合的操作系统&#xff0c;通常可选择Linux或WindowsServer操作系统。 上传、安装…

【C#】条码管理操作手册

前言&#xff1a;本文档为条码管理系统操作指南&#xff0c;介绍功能使用、参数配置、资源链接&#xff0c;以及异常的解决等。思维导图如下&#xff1a; 一、思维导图 二、功能操作–条码打印&#xff08;客户端&#xff09; 2.1 参数设置 功能介绍&#xff1a;二维码图片样…

Flink-----Yarn应用模式作业提交流程

Yarn应用模式作业提交流程 在Yarn当中又分为Session&#xff0c;PerJob&#xff0c;Application&#xff0c;建议和推荐使用独立集群的&#xff0c;其中就包含PerJob 和Application&#xff0c;但是1.17版本的Flink已将PerJob标记为过时&#xff0c;并且Application可以解决Pe…

Linux0.11内核源码解析-truncate.c

truncate文件只要实现释放指定i节点在设备上占用的所有逻辑块&#xff0c;包括直接块、一次间接块、二次间接块。从而将文件节点对应的文件长度截为0&#xff0c;并释放占用的设备空间。 索引节点的逻辑块连接方式 释放一次间接块 static void free_ind(int dev,int block) {…

基于阿里云 Flink+Hologres 搭建实时数仓

摘要&#xff1a;本文作者阿里云 Hologres 高级研发工程师张高迪&阿里云 Flink 技术内容工程师张英男&#xff0c;本篇内容将为您介绍如何通过实时计算 Flink 版和实时数仓 Hologres 搭建实时数仓。 Tips&#xff1a;点击「阅读原文」免费领取 5000CU*小时 Flink 云资源 背…

CSS基础 知识点总结

一.CSS简介 1.1 CSS简介 ① CSS指的是层叠样式表&#xff0c;用来控制网页外观的一门技术 ② CSS发展至今&#xff0c;经历过CSS1.0 CSS2.0 CSS2.1 CSS3.0这几个版本&#xff0c;CSS3.0是CSS最新版本 1.2 CSS引入方式 ① 在一个页面引入CSS&#xff0c;共有三种方式 外部…

【C语言基础】宏定义的用法详解

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

Arduino 入门学习笔记10 使用I2C的OLED屏幕

Arduino 入门学习笔记10 使用I2C的OLED屏幕 一、准备工具二、JMD0.96C-1介绍1. 显示屏参数2. SSD1306驱动芯片介绍&#xff1a; 三、使用Arduino开发步骤1. 安装库&#xff08;1&#xff09;Adafruit_GFX_Library 库&#xff08;2&#xff09;Adafruit_SSD1306 驱动库&#xff…

七夕特辑——3D爱心(可监听鼠标移动)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Lua 语言笔记(一)

1. 变量命名规范 弱类型语言(动态类型语言)&#xff0c;定义变量的时候&#xff0c;不需要类型修饰 而且&#xff0c;变量类型可以随时改变每行代码结束的时候&#xff0c;要不要分号都可以变量名 由数字&#xff0c;字母下划线组成&#xff0c;不能以数字开头&#xff0c;也不…