【Spring】-Bean的作用域和生命周期

news2025/1/8 4:20:16

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【Framework】
主要内容:Lombok的使用,Bean作用域的分类和修改。Singleton、Prototype。spring的执行流程,Bean的生命历程。

文章目录

  • 一、Bean的作用域
    • 1、 Lombok的使用(简化代码工具)
      • 1.1、什么是Lombok?为什么使用Lombok?
      • 1.2、使用Lombok的步骤?
      • 3、Lombok注解总结
    • 2、Bean的作用域
      • 2.1、什么是Bean的作用域?
      • 2.2、Bean作用域的分类
      • 2.3、设置Bean的作用域
        • 法一、使用注解
        • 法二、使用Xml方式
  • 二、Bean的生命周期
    • 1、spring执行流程
    • 2、Bean的生命周期
      • 2.1、Bean的生命周期的过程
      • 2.2、代码查看

一、Bean的作用域

1、 Lombok的使用(简化代码工具)

1.1、什么是Lombok?为什么使用Lombok?

Lombok是一个Java库,通过注解来简化Java代码的编写。它提供了一系列注解,可以自动插入代码,减少了Java开发中的样板代码。使用Lombok可以减少getter和setter方法的编写,简化构造函数的创建,自动生成toString、equals、hashCode等方法。

1.2、使用Lombok的步骤?

步骤A:从maven仓库复制 Lombok的依赖到 pom.xml文件中。
在这里插入图片描述
步骤A:在实体类上使用Lombok提供的注解:如 @Setter @Getter @ToString等
在这里插入图片描述
步骤C:在idea里下载Lombok插件,用于识别Java代码中的注解。(如果不下载插件,那么就无法识别注解)
在这里插入图片描述
如果没有安装Lombok,则想要调用user的属性没有下列提示信息,即无法识别注解:
在这里插入图片描述

3、Lombok注解总结

基本注解作用
@Getter自动添加getter方法(@Setter同理)
@ToString自动添加toString方法
@EqualsAndHashCode自动添加equals和hashcode方法
@NoArgsConstructor自动添加无参构造方法
@AllArgsConstructor自动添加全属性构造方法,顺序按照属性的定义顺序
@NonNull属性不能为null
@RequiredArgsConstructor自动添加必须属性的构造方法,final+@NonNull 的属性是必需
组合注解作用
@Data@Getter + @Setter + @ToString + @EqualsAndHashCode +
@RequiredArgsConstructor + @NoArgsConstructor
日志注解作用(写日志时会用到)
@Slf4j添加一个名为log的日志,使用Slf4j

2、Bean的作用域

2.1、什么是Bean的作用域?

在Java中,Bean的作用域指的是控制Bean实例的生命周期 和 可访问性的范围。
比如你有一个"User"类,你可以将它声明为Singleton作用域,这样整个程序就只有一个user对象,所有的代码都可以共享这一个对象。或者你将它声明为Prototype作用域,这样每次需要使用User对象时,都会创建一个新的User对象,每个对象都是独立的。

2.2、Bean作用域的分类

A:Singleton(单例):每个应用程序只有一个实例,所有请求都共享同一个实例(即 通过applicationContext.getBean()等方法 和 依赖注入(@Autowired) 都是同一个Bean对象)。
B:Prototype(原型):每次在该作用域下对Bean的请求都会创建新的Bean对象。(即 通过applicationContext.getBean()等方法 和 依赖注入(@Autowired) 都是新的实例Bean对象)。
C:request(请求): 每次HTTP请求都会创建新的Bean对象。【适用于SpringMVC】
D:Session(会话): 在HTTP的一个session(会话)中,只有一个Bean实例对象。【适用于SpringMVC】
E:application: 在一个HTTP server Context中,只有一个实例Bean对象。比如ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");获取IoC容器时, 在这个上下文context的作用域下,只使用一个Bean对象。【适用于SpringMVC】

2.3、设置Bean的作用域

法一、使用注解

单例作用域变原型作用域的代码演示:

A 理解当不设置作用域时,默认是单例作用域
需要改为原型作用域的情况:如果获取到对象后,需要当前对象作为源对象给临时对象赋值,就会出错,因为这时临时对象tmp和源对象user都指向了同一个对象,这时如果临时对象发生修改,那么源对象也会发生改变,得不偿失。所以要设置作用域范围,如果整个程序只需要使用一个不变的实体类对象,就可以使用单例作用域,否则使用原型作用域
B 设置作用域的方法:在存储Bean对象的时候在获取Bean的方法上使用Scope。有如下图两种方法。同时还可以使用xml的方式。
在这里插入图片描述

C 代码和运行结果如下:

//实体类
package test.entity;

import lombok.*;

@Setter
@Getter
@ToString
@AllArgsConstructor //包含所有参数的构造方法
@NoArgsConstructor  //无参构造方法
public class User {
    private int id;
    private String name;
}
//UserBeans,方法注解存储Bean对象
package test.conponent;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import test.entity.User;

@Component
public class UserBeans {
    @Bean(name = "User")
//    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//    @Scope("prototype")
    public User getUser(){
        User user = new User();
        user.setId(1);
        user.setName("admin");
        return user;
    }
}
//UserController 获取User对象,并给临时对象tmp赋值
package test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import test.entity.User;

@Controller
public class UserController {
    @Autowired
    private User user;

    public void run(){
        // 单例作用域时,user和tmp都是指向的同一个引用,tmp改变,user自然也改变
        System.out.println("原user"+user);
        User tmp = user;
        tmp.setId(2);
        tmp.setName("lihua");
        System.out.println("tmp"+tmp);
        System.out.println("给tmp赋值后的user:"+user);
        System.out.println("====================");
    }
}
//UserController2 获取当前User对象。
package test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import test.entity.User;

@Controller
public class UserController2 {
    @Autowired
    private User user;

    public void run(){
        System.out.println("UserController2:"+user);
    }
}

//App类的main方法中,调用获取上下文,并运行controller的方法。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import test.controller.UserController;
import test.controller.UserController2;

//lombok的使用,以及Bean的作用域、Bean的生命周期
public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = context.getBean("userController", UserController.class);
        userController.run();

        UserController2 userController2 = context.getBean("userController2", UserController2.class);
        userController2.run();

    }
}

运行结果:

userUser(id=1, name=admin)
tmpUser(id=2, name=lihua)
给tmp赋值后的user:User(id=2, name=lihua)
====================
UserController2User(id=2, name=lihua)

从代码运行结果可以看出,user给临时对象tmp赋值后,因为它俩指向的同一个对象,因此修改tmp后,user也被修改。

D:作修改: 在存储Bean时设置作用域Scope为原型作用域后,运行结果如下:

userUser(id=1, name=admin)
tmpUser(id=2, name=lihua)
给tmp赋值后的user:User(id=2, name=lihua)
====================
UserController2User(id=1, name=admin)

可以看到在UserController获取Bean并赋值tmp然后修改tmp后,UserController2获取Bean时,user对象并没有被改变,获取到的对象是源User,说明Bean不是单例了。
但是在UserController中获取Bean并赋值tmp然后修改tmp后,在该方法中User还是改变了,这是因为在下面方法中整个过程都是建立在调用了一次getBean的基础上来的,只有一次获取Bean的请求的前提,所以在该方法中是单例作用域。
在这里插入图片描述

法二、使用Xml方式
<bean id="userBean" class="com.example.User" scope="prototype"/>

二、Bean的生命周期

1、spring执行流程

在这里插入图片描述

2、Bean的生命周期

2.1、Bean的生命周期的过程

A:实例化,为Bean对象分配空间。
B:设置属性(对象装配),如果在当前Bean中需要其他Bean对象作为属性,则进行对象装配,注意设置属性比初始化早,防止在初始化时调用当前对象的属性对象。
C:初始化
1>执行各种通知
2>初始化前置方法
3>初始化方法(法一:注解方法PostConstruct,法二:Xml方式)
4> 初始化后置方法
D:使用
E:销毁

2.2、代码查看

以下代码展示了BeanNameAware接口的抽象方法重写的方法setBeanName(String s),用于展示初始化前的通知,初始化Bean对象方法PostConstruct,销毁Bean对象方法PreDestroy。同时初始化方法还可以使用Xml方式。

package test.controller;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import test.entity.User;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class UserControllerXml implements BeanNameAware {
    @Autowired
    private User user;

    @Override
    public void setBeanName(String s) {//执行各种通知的重写的方法
        System.out.println("do aware!(执行各种通知)");
    }

    @PostConstruct//初始化方法
    public void doPostStruct(){
        System.out.println("do PostStruct(初始化方法 )");
    }

    public void run(){//使用Bean方法
        System.out.println("使用Bean: "+user);
    }

    @PreDestroy
    public void doPreDestroy(){//销毁Bean的方法
        System.out.println("销毁Bean:");
    }
}

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

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

相关文章

树莓派+墨水屏 = DIY一个超慢速电影播放器

安装电子墨水屏这里使用了 Waveshare 的一款墨水屏&#xff0c;带驱动板。将驱动板插入树莓派的 GPIO 即完成屏幕和树莓派的连接。驱动这个屏幕需要启用树莓派的 SPI 接口。运行 sudo raspi-config 进入配置工具来启用 SPI 运行python例程 安装函数库 sudo apt-get update su…

指针笔试题详解

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.指针题写出下列程序的结…

Unity Windows上Inspector界面黑屏无法显示

问题描述&#xff1a;在Windows上Unity 打开工程Inspector显示黑色&#xff0c;不可用。如下图&#xff1a; 可能的问题。 Unity 设置Windows上默认渲染方式显卡不支持。 解决方案&#xff1a; 一、换一个好一点显卡 二、如下图&#xff1a;

Transformer的上下文学习能力

《Uncovering mesa-optimization algorithms in Transformers》 论文链接&#xff1a;https://arxiv.org/abs/2309.05858 为什么 transformer 性能这么好&#xff1f;它给众多大语言模型带来的上下文学习 (In-Context Learning) 能力是从何而来&#xff1f;在人工智能领域里&…

实验室安全教育与考试

目录 我的错题&#xff08;2个&#xff09;新知识题目&#xff08;10个&#xff09;刚开始不太理解的题目&#xff08;10个&#xff09;写在最后&#xff08;免责声明&#xff09; 我的错题&#xff08;2个&#xff09; 18.发生电气火灾时可以使用的灭火设备包括&#xff1a;&…

SAP Service服务重注册技术手册

当SAP服务被卸载后,或SAP虚拟机整机copy后(可能还需要涉及主机名更改),需要对SAP服务重注册。 在路径 \sapmnt\<SID>\ DVEBMGS00\exe下使用程序sapstartsrv.exe来卸载、安装SAP服务: 其中<SID>、NR参考Service中需要卸载的服务名(卸载后,Services列表中的SA…

【UE 粒子练习】08——LOD概述

目录 概念 应用举例 一、检查当前粒子系统中是否设置了LOD 二、添加LOD 三、LOD设置&#xff08;单个粒子发射器&#xff09; 四、LOD设置&#xff08;多个粒子发射器&#xff09; 概念 在 Unreal Engine 中&#xff0c;LOD&#xff08;Level of Detail&#xff0c;细…

Kubernetes 学习总结(37)—— Kubernetes 之 CoreDNS 企业级应用

前言 IP 地址会有变更&#xff0c;程序配置IP地址&#xff0c;所有涉及到此IP的地方都需要改变&#xff0c;对运维和研发都不友好。IP不容易被记住。引入域名来替换 IP&#xff0c;这样业务使用唯一标识域名&#xff0c;域名可以通过 DNS 服务器解析成 IP 供业务三层通信使用。…

时间复杂度、空间复杂度

一、时间复杂度 1、概念 时间复杂度&#xff1a;计算的是当一个问题量级增加的时间&#xff0c;时间增长的趋势&#xff1b; O&#xff08;大O表示法&#xff09;&#xff1a;渐进的时间复杂度 2、举例 ① 以下 for 循环的时间复杂度&#xff1a;O(1 3n) O(n) 去掉常数…

rom修改----安卓系列机型如何内置app 如何选择so文件内置

系统内置app的需求 在与各工作室对接中操作单中&#xff0c;很多需要内置客户特定的有些app到系统里&#xff0c;这样方便客户刷入固件后直接调用。例如内置apk 去开机引导 去usb调试 默认开启usb安全设置等等。那么很多app内置有不同的反应。有的可以直接内置。有的需要加so…

(十三)VBA常用基础知识:编程时各种常用操作之设值,取值,活动窗口设定

cell里设置内容的两个写法 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" End Sub2.cell里内容的取得 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" a Range(…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切(ROI)功能(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切&#xff08;ROI&#xff09;功能&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的图像剪切&#xff08;ROI&#xff09;功能的技术背景CameraExplorer如何使用图像剪切&#xff08;ROI&#xff09;功…

[nodejs]NVM使用指南

安装 官网链接 使用 # 版本号 nvm version# 显示node是运行在32位还是64位。 nvm arch# 显示已安装的列表 nvm list nvm ls# 使用制定版本node。可指定32/64位 nvm use [version] [arch]# 显示可安装的所有版本 nvm list available# 安装最新版本 nvm install latest# 安装指…

【Linux】系统编程简单线程池(C++)

目录 【1】线程池概念 【1.1】线程池 【1.2】线程池的应用场景 【1.3】线程池的种类 【1.4】线程池示例 【2】线程池代码 【1】线程池概念 【1.1】线程池 一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&a…

【新书推荐】用户画像:了解用户,助力企业成长 ——《用户画像:平台构建与业务实践》

文章目录 〇、引子一、什么是用户画像二、用户画像的优势三、如何实现用户画像四、用户画像应用中的问题五、总结新书推荐 —— 《用户画像&#xff1a;平台构建与业务实践》内容简介目录 〇、引子 在当今市场竞争激烈的时代&#xff0c;了解用户需求、提高用户体验已成为企业…

WebGL 雾化

目录 前言 如何实现雾化 线性雾化公式 雾化因子关系图 根据雾化因子计算片元颜色公式 示例程序&#xff08;Fog.js&#xff09; 代码详解​编辑 详解如何计算雾化因子&#xff08;clamp()&#xff09; 详解如何计算最终片元颜色&#xff08;根据雾化因子计算片元颜色…

二、搭建Java环境

搭建Java环境 搭建Java环境1.1.下载JDK1.2.在Win10下配置JDK环境 —————————————————————————————————————————————————— ———————————————————————————————————————————————…

李航老师《统计学习方法》第1章阅读笔记

1.1 统计学习 统计学习的特点 统计学习&#xff1a;计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析 现在人们提及机器学习时&#xff0c;往往指统计机器学习&#xff0c;所以可以认为本书介绍的是机器学习方法 统计学习的对象 统计学习研究的对象是数据(data)…

IDEA优化import导报-删除无用的包

选择File--Settings--Editor-General-Auto Import&#xff0c;勾选上下面框起来的即可&#xff0c;这样没有用到的包就会自己动被优化掉了~

了解SQL注入的类型、原理、检测与预防方法

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 梦想从未散场&#xff0c;传奇永不落幕&#xff0c;博主会持续更新优质网络知识、Python知识、Linux知识以及各种小技巧&#xff0c;愿你我共同在CSDN进步 目录 一、了解SQL注入 1. SQL注入是什么&#xff1f…