【SpringⅢ】Spring 的生命周期

目录

🥪1 Bean 的作用域

🥩1.1 singleton:单例模式

🍙1.2 prototype:原型模式

🍱1.3 Bean 的其他作用域

🍜2 Spring 生命周期(执行流程)

🥘2.1 启动容器

🍲 2.2 读取配置文件完成 Bean 初始化(实例化)

🎂2.3 将 Bean 对象放到容器中

🫕2.4 注入 Bean 属性(给当前类的属性DI,进行赋值)

🧁3 Bean 生命周期


1 Bean 的作用域

指定程序中某个变量的使用范围就叫做作用域。而 Bean 的作用域指的是 Bean 在 Spring 整个框架的行为模式。比如单例模式,就意味着 Bean 在整个 Spring 中只有一份,为全局共享的,如果有人修改这个值,那么另一个人拿到的,就是被修改过后的值。

1.1 singleton:单例模式

该作用域下的 Bean 在 IoC 容器中只存在一个实例,所以获取 Bean 或者注入 Bean(通过 @Autowired 注入)都是同一个对象

package com.java.demo.Model;public class User {private String name;private int Id;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", Id=" + Id +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return Id;}public void setId(int id) {Id = id;}
}

package com.java.demo.Model;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/**
* 公共类*/
@Component
public class Users {/** 公共对象 -> 默认单例模式*/@Bean("user")public User getUser(){User user = new User();user.setName("唐三藏");user.setId(11);return user;}
}

package com.java.demo.Controller;import com.java.demo.Model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate User user;public void doMethod(){User user1 = user;System.out.println("UserController 修改之前 :User -> " + user);user1.setName("如来佛祖");System.out.println("UserController 修改之后 :User -> " + user);}
}

package com.java.demo.Controller;import com.java.demo.Model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController2 {@Autowiredprivate User user;public void doMethod(){System.out.println("UserController2 :User -> " + user);}
}

package com.java.demo;import com.java.demo.Controller.UserController;
import com.java.demo.Controller.UserController2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/**
* 启动类*/
public class App {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = context.getBean("userController", UserController.class);userController.doMethod();UserController2 userController2 = context.getBean("userController2", UserController2.class);userController2.doMethod();}
}

输出:

UserController 修改之前 :User -> User{name='唐三藏', Id=11}
UserController 修改之后 :User -> User{name='如来佛祖', Id=11}
UserController2 :User -> User{name='如来佛祖', Id=11}

可以发现,单例模式中,user的姓名被修改了。

1.2 prototype:原型模式

在该作用域下,每次 Bean 请求都会创建新的实例,因此获取 Bean 以及注入 Bean 都是新的对象实例。

可以使用 @Scope 标签来设置作用域。@Scope 既可以修饰方法也可以修饰类,有以下两种写法:

1. 直接设置:@Scope("prototype")

2. 枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

package com.java.demo.Model;import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;/**
* 公共类*/
@Component
public class Users {/** 公共对象 -> 默认单例模式*/@Bean("user")//@Scope("prototype") // 原型模式/多例模式// 亦可写成:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public User getUser(){User user = new User();user.setName("唐三藏");user.setId(11);return user;}
}

输出:

UserController 修改之前 :User -> User{name='唐三藏', Id=11}
UserController 修改之后 :User -> User{name='如来佛祖', Id=11}
UserController2 :User -> User{name='唐三藏', Id=11}

1.3 Bean 的其他作用域

只适用于 Spring MVC 项目(Spring Web):

request:请求作用域。每次 http 请求都会创建新的 Bean 实例。一次 http 请求和响应共享                    Bean

session:会话作用域。一个 Http 会话共享一个 Bean。

application:应用作用域。表示的是一个 Context 容器共享一个作用域。

只适用于 websocket :

websocket 作用域

2 Spring 生命周期(执行流程)

2.1 启动容器

 2.2 读取配置文件完成 Bean 初始化(实例化)

2.3 将 Bean 对象放到容器中

这里只会扫描包路径上的类并且使用 Spring 的注解才可以被放到容器中。

扫描 com.java.demo 包下的 Spring 注解,像 @Controller、@Service、@Component、@Repository 

2.4 注入 Bean 属性(给当前类的属性DI,进行赋值)

如果 Bean 对象需要使用其他 Bean 对象作为属性,可以使用注解:@Autowired、@Resource

3 Bean 生命周期

Bean 的生命周期指的是 Bean 从诞生到销毁的整个生命过程,这样的过程就叫做生命周期,可以大致分为以下 5 个部分:

1. 实例化 Bean(为 Bean 分配内存空间)

2. 设置 Bean 属性(进行依赖注入,将依赖的 Bean 赋值到当前类的属性上)

3. Bean 初始化

           实现了各种 Aware 通知的⽅法,如 BeanNameAware、BeanFactoryAware、                         ApplicationContextAware 的接⼝⽅法;

           执⾏ BeanPostProcessor 初始化前置⽅法

           执⾏ @PostConstruct 初始化⽅法,依赖注⼊操作之后被执⾏;

           执⾏⾃⼰指定的 init-method ⽅法(如果有指定的话);

           执⾏ BeanPostProcessor 初始化后置⽅法

4. 使用 Bean

5. 销毁 Bean

           销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-                       method。

 

package com.java.demo;import com.java.demo.Model.User;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;public class BeanLifeComponent implements BeanNameAware {@Autowiredprivate User user;@Overridepublic void setBeanName(String s) {System.out.println("执行了 BeanNameAware -> " + s);}@PostConstructpublic void doPostConstruct(){System.out.println("执行了 @PostConstruct");System.out.println(user.toString());}public void myInit(){System.out.println("执行了 myInit");}@PreDestroypublic void doPreDestroy(){System.out.println("执行了 @PreDestroy");}public void sayHi(){System.out.println("使用了 Bean");}
}
package com.java.demo;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifeTest {public static void main(String[] args) {ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");BeanLifeComponent component =context.getBean("myBean", BeanLifeComponent.class);component.sayHi();context.close();}
}

 

输出:

执行了 BeanNameAware -> myBean
执行了 @PostConstruct
User{name='唐三藏', Id=11}
执行了 myInit
使用了 Bean
执行了 @PreDestroy


 

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

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

相关文章

[小尘送书-第二期]《从零开始读懂量子力学》由浅入深,解释科学原理;从手机到超导,量子无处不在;从微观到宏观,遐想人生的意义!

大家好,我是小尘,欢迎关注,一起交流学习!欢迎大家在CSDN后台私信我!一起讨论学习,讨论如何找到满意的工作! 本文目录 一、前言二、作者简介三、内容简介四、抽奖方式五、名家推介写在最后 一、前…

[containerd] 在Windows上使用IDEA远程调试containerd, ctr, containerd-shim

文章目录 1. containerd安装2. 源码编译3. 验证编译的二进制文件是否含有调试需要的信息3.1. objdump工具验证3.2. file工具验证3.3. dlv工具验证 4. debug 1. containerd安装 [Ubuntu 22.04] 安装containerd 2. 源码编译 主要步骤如下: 1、从github下载containe…

[Java] 单例设计模式详解

模式定义:保证一个类只有一个实例,并且提供一个全局访问点,时一种创建型模式 使用场景:重量级的对象,不需要多个实例,如线程池,数据库连接池 单例设计模式的实现 1.懒汉模式:延迟…

第一次后端复习整理(JVM、Redis、反射)

1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM,JVM超详细解析!!! 1.1 什么是JVM jvm是Java虚拟机 1.2 Java文件的编译过程 程序员编写代码形成.java文件经过javac编译成.class文件再通过JVM的类加载器进入运行时数据…

【141. 环形链表】

来源:力扣(LeetCode) 描述: 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环&#x…

JVM | 基于类加载的一次完全实践

引言 我在上篇文章:JVM | 类加载是怎么工作的 中为你介绍了Java的类加载器及其工作原理。我们简单回顾下:我用一个易于理解的类比带你逐步理解了类加载的流程和主要角色:引导类加载器,扩展类加载器和应用类加载器。并带你深入了解…

剑指offer12 矩阵中的路径 13 机器人的运动范围 34.二叉树中和为某一值得路径

class Solution { public:bool exist(vector<vector<char>>& board, string word) {int rowboard.size(),colboard[0].size();int index0,i0,j0;if(word.size()>row*col) return 0;//vector<vector<int>> visit[row][col];//标记当前位置有没有…

算法之归并排序算法

归并&#xff08;Merge&#xff09;排序法是将两个&#xff08;或两个以上&#xff09;有序表合并成一个新的有序表&#xff0c;即把待排序序列 分为若干个子序列&#xff0c;每个子序列是有序的。然后再把有序子序列合并为整体有序序列。 public class MergeSortTest {public …

到底什么是前后端分离

目录 Web 应用的开发主要有两种模式&#xff1a; 前后端不分离 前后端分离 总结 Web 应用的开发主要有两种模式&#xff1a; 前后端不分离 前后端分离 理解它们的区别有助于我们进行对应产品的测试工作。 前后端不分离 在早期&#xff0c;Web 应用开发主要采用前后端不…

linux系统下(centos7.9)安装Jenkins全流程

一、卸载历史版本 # rpm卸载 rpm -e jenkins# 检查是否卸载成功 rpm -ql jenkins# 彻底删除残留文件 find / -iname jenkins | xargs -n 1000 rm -rf二、环境依赖安装 yum -y install epel-releaseyum -y install daemonize三、安装Jenkins Jenkins官网传送带&#xff1a; …

《零基础入门学习Python》第071讲:GUI的终极选择:Tkinter8

虽然我们能用 tkinter 设计不少东西了&#xff0c;但是不少同学还是感觉对这个界面编程掌控得还不够多&#xff0c;说白了&#xff0c;就是我们现在还没办法随心所欲的去绘制我们想要的界面&#xff0c;但是不瞒你说&#xff0c;今天的这一节课将会给你的人生乃至人生观带来翻天…

苍穹外卖-day07

苍穹外卖-day07 本项目学自黑马程序员的《苍穹外卖》项目&#xff0c;是瑞吉外卖的Plus版本 功能更多&#xff0c;更加丰富。 结合资料&#xff0c;和自己对学习过程中的一些看法和问题解决情况上传课件笔记 视频&#xff1a;https://www.bilibili.com/video/BV1TP411v7v6/?sp…

Rust vs Go:常用语法对比(五)

题图来自 Rust vs Go 2023[1] 81. Round floating point number to integer Declare integer y and initialize it with the rounded value of floating point number x . Ties (when the fractional part of x is exactly .5) must be rounded up (to positive infinity). 按规…

KWP2000协议和OBD-K线

KWP2000最初是基于K线的诊断协议&#xff0c; 但是由于后来无法满足越来越复杂的需求&#xff0c;以及自身的局限性&#xff0c;厂商又将这套应用层协议移植到CAN上面&#xff0c;所以有KWP2000-K和KWP2000-CAN两个版本。 这篇文章主要讲基于K线的早期版本协议&#xff0c;认…

零售企业信息化系统建设与应用解决方案

导读&#xff1a;原文《零售企业信息化系统建设与应用解决方案ppt》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 如需获取完整的电子版内容参考学习…

基于Kaggle训练集预测的多层人工神经网络的能源消耗的时间序列预测(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f308;3 Matlab代码实现 &#x1f389;4 参考文献 &#x1f4a5;1 概述 本文为能源消耗的时间序列预测&#xff0c;在Matlab中实现。该预测采用多层人工神经网络&#xff0c;基于Kaggle训练集预测未来能源消耗。 &am…

使用镜像搭建nacos集群

安装并配置 docker 1 先安装docker //1.查看操作系统的发行版号 uname -r//2.安装依赖软件包 yum install -y yum-utils device-mapper-persistent-data lvm2//3.设置yum镜像源 //官方源&#xff08;慢&#xff09; yum-config-manager --add-repo http://download.docker.co…

第十二章:priority_queue类

系列文章目录 文章目录 系列文章目录前言priority_queue的介绍priority_queue的使用容器适配器什么是容器适配器STL标准库中stack和queue的底层结构 总结 前言 priority_queue是容器适配器&#xff0c;底层封装了STL容器。 priority_queue的介绍 priority_queue文档介绍 优先…

IDEA中文UT方法执行报错问题、wps默认保存格式

wps默认保存格式、IDEA中文UT方法执行报错问题 背景 1、wps修改文件后&#xff0c;编码格式从UTF-8-bom变成UTF-8&#xff08;notepad可以查看&#xff09;&#xff1b; 2、IDEA中文UT执行报错&#xff1a; 解决方案 1、语言设置中不要勾选 “Beta版。。。。” 2、cmd中执…

layui框架学习(33:流加载模块)

Layui中的流加载模块flow主要支持信息流加载和图片懒加载两部分内容&#xff0c;前者是指动态加载后续内容&#xff0c;示例的话可以参考csdn个人博客主页&#xff0c;鼠标移动到页面底部时自动加载更多内容&#xff0c;而后者是指页面显示图片时才会延迟加载图片信息。   fl…