【SpringⅢ】Spring 的生命周期

news2024/9/26 5:20:36

目录

🥪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;

    @Override
    public 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 {
    @Autowired
    private 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 {
    @Autowired
    private 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 {
    @Autowired
    private User user;

    @Override
    public void setBeanName(String s) {
        System.out.println("执行了 BeanNameAware -> " + s);
    }

    @PostConstruct
    public void doPostConstruct(){
        System.out.println("执行了 @PostConstruct");
        System.out.println(user.toString());
    }

    public void myInit(){
        System.out.println("执行了 myInit");
    }

    @PreDestroy
    public 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.coloradmin.cn/o/805456.html

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

相关文章

【代理模式】了解篇:静态代理 动态代理~

目录 1、什么是代理模式? 2、静态代理 3、动态代理 3.1 JDK动态代理类 3.2 CGLIB动态代理类 4、JDK动态代理和CGLIB动态代理的区别? 1、什么是代理模式? 定义: 代理模式就是为其他对象提供一种代理以控制这个对象的访问。在某…

图像 检测 - FCOS: Fully Convolutional One-Stage Object Detection (ICCV 2019)

FCOS: Fully Convolutional One-Stage Object Detection - 全卷积一阶段目标检测(ICCV 2019) 摘要1. 引言2. 相关工作3. 我们的方法3.1 全卷积一阶目标检测器3.2 FCOS的FPN多级预测3.3 FCOS中心度 4. 实验4.1 消融研究4.1.1 FPN多级预测4.1.2 有无中心度…

python学习时与chatgpt4对话的一些感悟

今天学SCENIC教程,看到里面有一句不是很懂 If you run this from a python script instead of a Jupyter notebook, please enclose the code in a if __name__ __main__: construct. 现在把和chatgpt4问答的内容发上来,确实是很厉害 没有太看懂&…

Verilog语法学习——LV6_多功能数据处理器

LV6_多功能数据处理器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a…

蓝海卓越计费管理系统存在弱口令

连伟人的一生都充满了那么大的艰辛,一个平凡的人吃点苦又算得了什么呢? 漏洞描述 蓝海卓越计费管理系统存在弱口令漏洞 漏洞复现 访问漏洞url: 输入默认的账号密码:admin/admin 登录成功 文笔生疏,措辞浅薄&#…

小米手机MIUI优化的影响

1. 小/红米手机的MIUI优化选项 2. MIUI优化选项的影响 2.1 MIUI优化会影响应用信息展示 MIUI优化选项会影响到应用信息的内容展示,具体如下图所示: 如果我们需要在应用信息里展示自启动入口,那我们就需要开启MIUI优化。 2.2 MIUI优化会影…

C++对C的加强(全)

目录 C对C的加强 命名空间 为什么要使用命名空间 怎么使用命名空间 命名空间的定义 命名空间的使用 使用域解析符 :: 使用using声明 内联命名空间 嵌套命名空间 随时将新的成员加入命名空间 命名空间中 函数的声明和实现分开 无名命名空间 命名空间取别名 使用u…

苍穹外卖day08——地址簿+用户下单+订单支付(做不了)

导入地址簿——需求分析与设计 产品原型 接口设计 数据库设计 导入地址簿——代码导入 导入地址簿——功能测试 没有问题 用户下单——需求分析与设计 业务说明 业务流程 接口设计 数据库设计 用户下单——代码开发 DTO设计和VO设计 Controller层中 RequestMapping(&q…

Clock时钟电路PCB设计布局布线要求

时钟电路就是类似像时钟一样准确运动的震荡电路,任何工作都是依照时间顺序,那么产生这个时间的电路就是时钟电路,时钟电路一般是由晶体振荡器、晶振、控制芯片以及匹配电容组成,如图1所示。 图1 时钟电路 针对时钟电路PCB设计有以…

小白的机器学习之路(四)神经网络的初步认识:基于pytorch搭建自己的神经网络

小白的机器学习之路(四) 引子神经网络的基本结构反向传播算法和激活函数优化器如何通过pytorch搭建自己的BP network 引子 当前交通大数据业务的需要,需要承担一部分算法工作(数据处理),考虑到上次研究深度…

用哪些指标可以抓住现货白银趋势?

在现货白银走势分类中,走势一般来说之分成三类,一个是上升,一个是下跌,还有一个是水平。对于投资者来说,趋势,也就是上升或者下跌是我们喜爱的,那么我们如何捕捉这种趋势呢?我们可以…

【雕爷学编程】MicroPython动手做(02)——尝试搭建K210开发板的IDE环境

知识点:简单了解K210芯片 2018年9月6日,嘉楠科技推出自主设计研发的全球首款基于RISC-V的量产商用边缘智能计算芯片勘智K210。该芯片依托于完全自主研发的AI神经网络加速器KPU,具备自主IP、视听兼具与可编程能力三大特点,能够充分适配多个业务场景的需求。作为嘉楠科…

Verilog语法学习——LV9_使用子模块实现三输入数的大小比较

LV9_使用子模块实现三输入数的大小比较 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 在数字芯片设计中,通常把完成特定功能且相对独立的…

C#之泛型

目录 一、概述 二、C#中的泛型 继续栈的示例 三、泛型类 (一)声明泛型类 (二)创建构造类型 (三)创建变量和实例 (四)比较泛型和非泛型栈 四、类型参数的约束 (一…

系统集成中级计算汇总

基本计算: EV 挣值 (实际完成的工作量) AC 实际发生的花费 PV 计划花费(预算) CV 成本 SV 进度 CV 和 SV 的计算 都是通过EV 减去另一个值 CV EV-AC SV EV-PV 成本 chengben C 开头 所以CV 是成本 CV 中有个C 所以用到的是 AC ,另外一个则是剩余的PV CV SV 计算…

LeetCode621.Task-Scheduler<任务调度器>

题目: 思路: 思路个锤子,看完题根本不会写. 看的答案 : 【任务调度器】C 桶子_配图理解 - 任务调度器 - 力扣(LeetCode) 是一种贪心的思想.数学问题. 一个是任务的种类,一个是任务的最大的一个值。 代码是: //cod…

【组内工作】木马回联

文章目录 C2服务器安装和运行方法CrossC2运行方法sliver运行方法empire安装方法DeimosC2安装教程TrevorC2安装教程: C2服务器的流量特征CrossC21. 心跳包2. 命令3. ja3/ja3s Sliver1. http2. https empirehttphttps DeimosC2https TrevorC2 C2服务器安装和运行方法 …

【VTK】读取一个 STL 文件,并使用 Qt 显示出来,在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 A.hA.cppRef. 直接先把效果放出来&#xff0c;有需要就往下看。 A.h // A.h #pragma once#include <QtWidgets/QMainWindow> #include "…

【Qt】QML-02:QQuickView用法

1、先看demo QtCreator自动生成的工程是使用QQmlApplicationEngine来加载qml文件&#xff0c;下面的demo将使用QQuickView来加载qml文件 #include <QGuiApplication> #include <QtQuick/QQuickView>int main(int argc, char *argv[]) {QGuiApplication app(argc,…

蓝桥杯单片机第八届国赛 真题+代码

iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础&#xff0c;根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求&#xff0c;进行代码调试和修改。 */ #include <STC1…