JavaEE进阶:Bean 作⽤域和⽣命周期

news2024/11/15 18:05:14

文章目录

  • 一、Bean 的作用域问题
    • 1、案例
    • 2、分析
  • 二、作用域定义
    • 1、Bean 的 6 种作用域
      • ① singleton
      • ② prototype
      • ③ request
      • ④ session
      • ⑤ application
      • ⑥ websocket
      • ⑦ 单例作用域(singleton)和全局作用域(application)区别
    • 2、设置作用域
    • 3、案例修改
  • 三、Bean 原理分析
    • 1、Bean 执行流程
    • 2、Bean 生命周期
      • ① 实例化和初始化的区别
      • ② 生命流程的“故事”
      • ③ 生命周期演示
      • ④ 思考:为什么要先设置属性在进行初始化呢?

一、Bean 的作用域问题

1、案例

先定义一个 Cat 类:

public class Cat {
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

定义一个公共的 Bean:

@Component
public class CatBeans {
    @Bean
    public Cat cat() {
        Cat cat = new Cat();
        cat.setId(1);
        cat.setName("喵喵喵");
        cat.setAge(8);
        return cat;
    }
}

小明 在使用时,修改了 Bean:

@Controller
public class ScopeController {
    @Autowired
    private Cat cat;

    public void doScope() {
        System.out.println("Do scope controller.");
        System.out.println("原数据:" + cat.toString());
        // 修改
        Cat cat2 = new Cat();
        cat2.setName("喵喵");
        System.out.println("修改之后的数据: " + cat2.toString());
    }
}

我们之后如果还要用这个 Bean:

@Controller
public class ScopeController2 {
    @Resource
    private Cat cat;

    public void doSCope(){
        System.out.println("Do scope controller 2.");
        System.out.println(cat.toString());
    }
}

测试:

public class App {
    public static void main(String[] args) {
        // 1.得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
                
        ScopeController scopeController =
                context.getBean("scopeController", ScopeController.class);
        scopeController.doScope();
        System.out.println();
        
        ScopeController2 scopeController2 =
                context.getBean("scopeController2", ScopeController2.class);
        scopeController2.doSCope();
        System.out.println();
    }
}

运行结果为:
在这里插入图片描述

2、分析

Spring 中 Bean 默认情况下是单例模式,即 cat 和 cat1 都指向了同一块区域,我们无论是修改 cat 还是 cat1 都会对这个 Bean 造成修改。

二、作用域定义

Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份。

1、Bean 的 6 种作用域

Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作⽤域。Spring有 6 种作⽤域,
最后四种是基于 Spring MVC ⽣效的(主要学习前四种 作用域):

  • singleton:单例作⽤域(默认作用域),只有一个全局对象。
  • prototype:原型作⽤域(多例作⽤域)每次访问都会创建一个新的对象。
  • request:请求作⽤域(只能在 Spring MVC 中使用),每次 HTTP 请求都会创建一个对象。
  • session:回话作⽤域(只能在 Spring MVC 中使用),每次(session)会话使用一个 bean 对象。
  • application:全局作⽤域(只能在 Spring MVC 中使用),一个 http servlet context 中共享一个对象。
  • websocket:HTTP WebSocket 作⽤域(只能在 Web Socket 中使用

下面是官方的资料:

① singleton

  • 官⽅说明:(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
  • 描述:该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过 applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀ 个对象。
  • 场景:通常无状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新
  • 备注:Spring默认选择该作⽤域

② prototype

  • 官⽅说明:Scopes a single bean definition to any number of object instances.
  • 描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过 applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的 对象实例。
  • 场景:通常有状态的Bean使⽤该作⽤域

③ request

  • 官⽅说明:Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:每次http请求会创建新的Bean实例,类似于prototype
  • 场景:⼀次http的请求和响应的共享Bean
  • 备注:限定SpringMVC中使⽤

④ session

  • 官⽅说明:Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:在⼀个http session中,定义⼀个Bean实例
  • 场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
  • 备注:限定SpringMVC中使⽤

⑤ application

  • 官⽅说明:Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:在⼀个http servlet Context中,定义⼀个Bean实例
  • 场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息
  • 备注:限定SpringMVC中使⽤

⑥ websocket

  • 官⽅说明:Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例
  • 场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean。
  • 备注:限定Spring WebSocket中使⽤

⑦ 单例作用域(singleton)和全局作用域(application)区别

  • singleton 是 Spring Core 的作⽤域;application 是 Spring Web 中的作⽤域;
  • singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。

2、设置作用域

我们可以使用 @Scope 标签来声明 Bean 的作用域,代码如下:

@Component
public class MyComponent {
//    @Scope("prototype")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean(name = "c1")
    public void doComponent1() {
        System.out.println("Do user component1.");
    }
}

使用 @Scope 标签声明 Bean 作用域的两种方式:

  1. 直接输入作用域:@Scope(“prototype”)
  2. 采用枚举的方式:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

注意

  • 在使用第一种方式的时候,要注意不能拼写错误;
  • 使用第二种方式就不容易写错(idea 自带提示).

3、案例修改

通过刚刚的学习,我们知道了:可以用 @Scope 标签来声明 Bean 作用域。我们之前也分析过,出现问题的原因,即 Spring 中默认为 单例作用域(singleton),那我们只需要将公共的 Bean 的作用域修改为 多例作用域(prototype)即可,修改如下:

@Component
public class CatBeans {
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public Cat cat() {
        Cat cat = new Cat();
        cat.setId(1);
        cat.setName("喵喵喵");
        cat.setAge(8);
        return cat;
    }
}

此时我们再运行程序,结果为:
在这里插入图片描述

三、Bean 原理分析

1、Bean 执行流程

Bean 执⾏流程(Spring 执⾏流程):

  • 启动 Spring 容器
  • 实例化 Bean(分配内存空间,从⽆到有)
  • Bean 注册到 Spring 中(存操作)
  • 将 Bean 装配到需要的类中(取操作)
    在这里插入图片描述

2、Bean 生命周期

Bean 生命周期:

  1. 实例化(≠初始化):分配内存空间
  2. 设置属性:依赖注入 DI
  3. 初始化:
    1. 执行各种通知
    2. 初始化的前置方法:xml 文件里 定义的 init-method | @PostConstruct
    3. 初始化方法
    4. 初始化的后置方法
  4. 使用 Bean
  5. 销毁 Bean

① 实例化和初始化的区别

  • 实例化:是指创建一个对象的过程。这个过程中会在堆中开辟内存,将一些非静态的方法,变量存放在里面。在程序执行的过程中,可以创建多个对象,既多次实例化。每次实例化都会开辟一块新的内存。
  • 初始化:是完成程序执行前的准备工作。在这个阶段,静态的(变量,方法,代码块)会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。

② 生命流程的“故事”

以买房为例:

  1. 买房(实例化)
  2. 装修(设置属性)
  3. 买家具(初始化)
  4. 入住(使用 Bean)
  5. 卖方(销毁 Bean)

③ 生命周期演示

//@Component
public class BeanLifeComponent implements BeanNameAware {

    public void setBeanName(String s) {
        System.out.println("执行了 Bean Name 通知:" +
                s);
    }

    /**
     * 方法名随意定义
     * xml中 init-method 指定的方法
     */
    public void initMethod(){
        System.out.println("执行了 init-method 方法");
    }

    /**
     * 方法名随意定义
     */
    @PostConstruct
    public void myPostConstruct(){
        System.out.println("执行了 PostConstruct 方法");
    }

    /**
     * 销毁前执行方法
     */
    @PreDestroy
    public void myPreDestroy(){
        System.out.println("执行了 PreDestroy 方法");
    }

    public void run(){
        System.out.println("执行了 run 方法");
    }
}

xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <content:component-scan base-package="com.wzr"></content:component-scan>

    <bean id="beanlife" class="com.wzr.controller.BeanLifeComponent"
          init-method="initMethod"></bean>
</beans>

调用类:

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        BeanLifeComponent component =
                context.getBean("beanlife",BeanLifeComponent.class);
        component.run();
        context.destroy();
    }
}

在这里插入图片描述

④ 思考:为什么要先设置属性在进行初始化呢?

这就是因为,我们初始化过程中,有很多的方法,这些方法可能会调用某个属性,如果没有设置属性,就会报错(空指向异常)

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

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

相关文章

学生花卉网网页设计作品 学生鲜花网页模板 简单在线花店主页成品 鲜花网页制作 HTML学生花店商城网站作业设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

vue3 创建项目、安装依赖、启动项目

1. 搭建vue开发环境 下载安装最新版node.js https://blog.csdn.net/weixin_41192489/article/details/117979077 2. 执行项目创建命令 打开命令行工具 cnpm init vuelatest无 cnpm 的朋友先执行 npm i cnpm 遇到这种提示时&#xff0c;输入 y 回车 3. 选择项目创建配置 参考下…

安卓玩机搞机技巧综合资源-----关闭miui广告 怎么省电 替换开机动画 LOGO 锁屏 壁纸等等【五】

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

Windows OpenGL ES 图像白平衡色温

目录 一.OpenGL ES 图像白平衡色温 1.原始图片2.效果演示 二.OpenGL ES 图像白平衡色温源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零…

Sentinel规则持久化

Sentinel规则持久化 根据之前遇到的问题可以看出&#xff0c;当服务关闭后Sentinel就不会再有对应的信息&#xff0c;也就是临时保存的&#xff0c;下面就是要进行持久化的保存 将限流配置规则持久化进Nacos保存&#xff0c;只要刷新8401某个rest地址&#xff0c;sentinel控制台…

解决安装 CentOS 8 错误: Error setting up base repository

1. 问题 安装 CentOS-8 常常会遇到这样的问题&#xff0c;即在安装过程中会发现软件源的设置&#xff0c;无论怎样都会显示这样的错误 “Error setting up base repository”。 导致这一问题的原因是&#xff0c;由于 CentOS-8 的生命周期较短&#xff0c;其基本的软件库已早…

数字化成汽车零部件发展趋势,数商云SRM系统库存管理模块助力企业转型升级

近年来&#xff0c;随着人工智能、物联网等技术应用边界不断拓展&#xff0c;数字化转型逐渐成为企业发展的趋势。零部件是汽车产业发展最为重要的基础&#xff0c;汽车零部件制造作为突破的重点领域之一&#xff0c;引领汽车零部件行业发展可加快提升汽车产业核心竞争力&#…

2022-03-18-SpringBoot

layout: post #标题配置 title: SpringBoot #时间配置 date: 2022-03-18 18:54:00 0800 #目录配置 categories: 框架 #标签配置 tag: 学习笔记 content {:toc} 一.SpringBoot基础 1-今日内容 Spring概述、快速入门SpringBoot配置SpringBoot整合 2-SpringBoot概述 SpringB…

【Cycle-Interactive GAN:弱光图像增强】

Cycle-Interactive Generative Adversarial Network for Robust Unsupervised Low-Light Enhancement &#xff08;基于循环交互式生成式对抗网络的鲁棒无监督弱光增强&#xff09; 近年来的无监督弱光增强方法摆脱了对成对训练数据拟合的基本限制&#xff0c;在调节图像亮度…

今年大促季,阿里云容器服务有哪些技术和应用新突破?

联合作者&#xff1a;志敏&#xff0c;冬岛&#xff0c;戒空&#xff0c;邓隽&#xff0c;佳旭&#xff0c;谢乘胜&#xff0c;元毅&#xff0c;溪洋在 2022 年的双 11 大促季中&#xff0c;阿里云容器服务&#xff08;简称 ACK&#xff09;、容器镜像服务&#xff08;简称 ACR…

教你如何基于Redis来实现高性能延时消息队列!

最近在倒腾自建博客后端系统&#xff0c;需要用到延时任务的功能&#xff0c;但手头只有一套MySQL和Redis&#xff0c;如果搞一套MQ成本有点大&#xff0c;于是想着用redis实现延时消息队列。有些场景用数据库的定时扫表也能简单实现延时消息的功能&#xff0c;不过对于我这边的…

Frida-Dexdump 脱壳工具下载使用以及相关技术介绍

Frida-Dexdump 脱壳工具下载使用以及相关技术介绍 文章目录Frida-Dexdump 脱壳工具下载使用以及相关技术介绍前言一、查壳、反编译、APK工具推荐二、查壳1.方式12.方式二三、脱壳1.启动frida服务2.方式一3.方式二四、反编译总结前言 本案例使用的App是&#xff1a;引力播.apk&…

多无人机空中机器人施工任务分配(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 空中机器人作为近年来新兴的热点得到了广泛的关注。小型空中机器人在没有外界卫星定位信号的前提下的导航是空中机器人的研究内…

cmip6数据处理、动力降尺度、统计降尺度、制备CMIP6的WRF驱动数据

收录了CMIP6数据处理方法&#xff0c;典型案例分析实践过程中出现的一些问题&#xff0c;及技术&#xff08;下拉查看&#xff09; 国际耦合模式比较计划进入新的阶段——第六阶段&#xff08;CMIP6&#xff09;&#xff0c;这将为气候变化研究领域提供更丰富的全球气候模式数…

Python字符串格式化的三种方式

Python格式化的三种方式 根据类型定义的格式化 - %s 字符串格式化使用操作符 % 来实现&#xff0c; 示例 my name is %s,my age is %s % (neo, 18) 格式符: %s 连接符&#xff1a;格式化字符串与格式符变量之间用一个 % 连接&#xff0c; % 两边各有一个空格 附&#xff1a;…

08、SpringBoot入门简介

1、简介 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。 人们把 Spring Boot 称为搭建程序的脚手架。其最主要作用就是帮我们快速的构建庞大的 Spring 项目&#xff0c;并且尽可能的减少一切 XML 配置…

我用Echarts图表分析巴西队历年战绩,预测卡塔尔世界杯能否夺冠

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;前端领域新星创作者、华为云享专家、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff…

baostock量化怎样下载十档行情数据?

baostock量化对数据的下载其实就是通过计算的方式去决策股票的买卖。目前根据量化计算方式其实跟量子计算一点关系都没有。那么&#xff0c;都说在股票量化交易过程中&#xff0c;可以利用l2股票接口来获取策略选股的方案是很普遍的&#xff0c;利用数据接口下载十档行情&#…

[附源码]Python计算机毕业设计SSM基于协同过滤算法的甜品推荐系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Echart柱状图表排名

var charts { // 按顺序排列从大到小 cityList: [38号点, 8号点, 15号点, 16号点, 24号点], cityData: [7500, 6200, 5700, 4200, 3500] } var top10CityList charts.cityList var top10CityData charts.cityData var color [#ff9500, #02d8f9, #027fff] var color…