Bean的作用域和生命周期(下)

简介: Bean的作用域和生命周期(下)

request — 请求作用域


描述🍭

每次 HTTP 请求都会创建一个新的实例

一次 HTTP 的请求和响应共享同一个 Bean

适用场景🍭

在 SpringMVC 中使用

session — 会话作用域


描述🍭

在一个 HTTP Session 中创建一个新的实例

举个栗子🌰

用户 Jack 登录他的账号, 在 Jack 登陆状态中, Bean 处于共享状态(针对于 Jack 的信息)

另一个用户 Tom 登录他的账号, 在 Tom 登陆状态中, Bean 处于共享状态(针对于 Tom 的信息)

对于 Jack 和 Tom, 他们的 Bean 是隔离而非共享

适用场景🍭

在 SpringMVC 中使用

application — 全局作用域


描述🍭

在一个 HTTP Servlet Context 中创建一个新的实例

适用场景🍭

在 SpringMVC 中使用

websocket — HTTP WebSocket 作用域


描述🍭

在一个 HTTP WebSocket 的生命周期中创建一个新的实例

WebSocket 的每次会话中, 保存了一个 Map 结构的头信息, 用于包裹客户端消息头

第一次初始化后, 直到 WebSocket 结束都是同一个 Bean

适用场景🍭

在 SpringMVC 中使用

对比单例作用域与全局作用域


  1. singleton 是 Spring Core 的作用域
    application 是 Spring Web 的作用域
  2. singleton 作用于 IOC 容器
    application 作用于 Servlet 容器

设置作用域


利用 @Scope() 设置作用域

作用域 设置方式
singleton — 单例作用域 @Scope("singleton") / @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON))
prototype — 原型作用域 @Scope("prototype") / @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
request — 请求作用域 @Scope("request") / @Scope(WebApplicationContext.SCOPE_REQUEST)
session — 会话作用域 @Scope("session") / @Scope(WebApplicationContext.SCOPE_SESSION)
application — 全局作用域 @Scope("application") / @Scope(WebApplicationContext.SCOPE_APPLICATION)

以 prototype — 原型作用域 为例

🔎Spring的执行流程


  1. 启动容器(项目)
  2. 读取xml配置文件, 将 Bean 初始化
  • 直接注册 Bean(<bean id="" class=""></bean>)
  • 配置根扫描路径(<content:component-scan base-package=""></content:component-scan>)
  1. 将 Bean 存储至 Spring
  2. 从 Spring 中读取 Bean

启动容器(项目)

读取xml配置文件, 将 Bean 初始化

将 Bean 存储至 Spring

从 Spring 中读取 Bean

🔎Bean的生命周期


Bean 的生命周期分为 5 个部分

  1. 实例化 Bean(为 Bean 分配内存空间)
    实例化是一个从无到有的过程, 将字节码转换成内存中的对象, 分配了内存空间 → 类似于 JVM 的加载过程
  2. 设置属性(Bean 注入)
  3. 初始化 Bean
  • 实现了各种 Aware 的通知方法, 例如 BeanNameAware, BeanFactoryAware…
  • 执行 BeanPostProcessor 初始化的前置方法
  • 执行 @PostConstruct 初始化方法
  • 执行指定的 init-method 初始化方法(如果有)
  • 执行 BeanPostProcessor 初始化的后置方法
  1. 使用 Bean
  2. 销毁 Bean

对比 @PostConstruct 与 init-method

相同🍭

都是初始化方法

不同🍭

@PostConstruct 使用注解进行初始化

init-method 使用 xml 进行初始化(<bean></bean>)

执行顺序 @PostConstruct > init-method

对Bean的生命周期的解释


实例化🍂

类似于购买了一套毛坯房

设置属性(Bean 注入)🍂

为毛坯房挑选装修风格, 装修材料(引入外部资源)

Bean 初始化🍂

装修毛坯房

  • 实现了各种 Aware 的通知方法🍂
    雇用各种装修工人进行装修(水工, 电工, 瓦工…)
  • 执行 BeanPostProcessor 初始化的前置方法🍂
    装修工人到达施工现场, 制定装修方案
  • 执行初始化方法🍂
    有 2 批装修工人
    一批使用现代化装修工具但经验不足(@PostConstruct)
    另一批使用传统装修工具但经验充足(init-method)
    注解的出现时间对比xml较晚
    优先雇用使用现代化装修工具但经验不足的工人 → 执行顺序 @PostConstruct > init-method
  • 执行 BeanPostProcessor 初始化的后置方法🍂
    完成装修任务的工人做的一些善后工作(清理装修的垃圾…)

使用Bean🍂

购房者搬进装修好的房子

销毁Bean🍂

购房者将房子卖掉

示例


示例代码🍂

package com.demo.component;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
//@Component
public class BeanLifeComponent implements BeanNameAware {
    @Override
    public void setBeanName(String s) {
        System.out.println("执行了通知");
    }
    public void init() {
        System.out.println("执行了 Init-method");
    }
    @PostConstruct
    public void postConstruct() {
        System.out.println("执行了 @PostConstruct");
    }
    @PreDestroy
    public void preDestroy() {
        System.out.println("执行 PreDestroy — 销毁方法");
    }

配置文件🍂

<?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.demo"></content:component-scan>
        <bean id="myComponent" class="com.demo.component.BeanLifeComponent"
              init-method="init"></bean>
</beans>

示例代码🍂

public static void main(String[] args) {
    // ClassPathXmlApplicationContext 包含销毁方法
    // ApplicationContext 不包含销毁方法
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    BeanLifeComponent lifeComponent = context.getBean("myComponent", BeanLifeComponent.class);
    System.out.println("使用 Bean");
    // 销毁 Bean
    context.destroy();
}

🔎结尾

创作不易,如果对您有帮助,希望您能点个免费的赞👍

大家有什么不太理解的,可以私信或者评论区留言,一起加油

相关文章
|
6月前
|
XML Java 数据格式
SpringBean的生命周期
SpringBean的生命周期
63 0
|
6月前
|
前端开发 Java 开发者
Bean的生命周期和作用域
Bean的生命周期和作用域
|
2月前
|
Java 开发者 Spring
Bean生命周期介绍
Spring Boot 的 Bean 生命周期管理是其核心功能之一,负责应用程序中 Java 对象(称为 Beans)的创建、配置、初始化和销毁。此功能提供了灵活的依赖注入方式,便于组件化开发。Bean 生命周期包括实例化、属性注入、初始化方法调用、使用及销毁方法调用等阶段。应用场景涵盖依赖注入、配置管理、组件扩展及切面编程。通过实现特定接口或注解,开发者可轻松管理对象生命周期,优化应用性能。示例代码展示了如何通过日志观察 Bean 生命周期的不同阶段。
102 3
|
6月前
|
XML Java 数据格式
Spring框架学习 -- Bean的生命周期和作用域
Spring框架学习 -- Bean的生命周期和作用域
53 2
|
6月前
|
存储 设计模式 Java
Bean 作用域和生命周期
Bean 作用域和生命周期
|
前端开发 Java C++
Bean的作用域
Bean 常见的 6 种作用域
|
6月前
|
Java 开发者 Spring
Bean 的生命周期了解么
Bean 的生命周期了解么
|
11月前
|
Java Spring 容器
bean的生命周期
bean的生命周期
54 0
|
存储 安全 Java
Bean 的作用域和生命周期
Bean 的作用域和生命周期
71 1
|
Java 容器 Spring
bean的作用域和生命周期和后置处理器以及作用域对生命周期的影响~
bean的作用域和生命周期和后置处理器以及作用域对生命周期的影响~