【spring原理】Bean的作用域与生命周期

Bean的作用域

在编程中,Bean的作用域(Scope) 是指一个Bean对象的生命周期及其在应用上下文中的可见性。特别是在Spring框架中,Bean的作用域决定了一个Bean是如何被创建、共享和销毁的。以下是Spring中常用的Bean作用域及其特点:


1. Singleton(单例,默认作用域)

  • 描述: 整个Spring容器中仅存在一个共享的Bean实例。
  • 特点 :
    • 每次请求该Bean时,都会返回同一个实例。
    • 默认作用域,适用于无状态的Bean。
  • 应用场景: 大多数服务类、工具类、无状态组件。

2. Prototype(原型)

  • 描述: 每次请求时都会创建一个新的Bean实例。
  • 特点 :
    • 每次注入或通过ApplicationContext.getBean()获取时,都会返回一个新的对象。
    • Spring容器只负责创建实例,生命周期交由调用方管理。
  • 应用场景: 需要保持独立状态的组件,例如每个用户的会话对象。

3. Request

  • 描述: 在Web应用中,为每个HTTP请求创建一个新的Bean实例。
  • 特点 :
    • 每个HTTP请求会对应一个独立的Bean实例。
    • 仅在请求周期内有效,请求结束后自动销毁。
  • 应用场景: 与单个HTTP请求相关的状态信息。

4. Session

  • 描述: 在Web应用中,为每个HTTP会话创建一个Bean实例。
  • 特点 :
    • 在同一个HTTP会话中共享该Bean实例。
    • 会话结束后,Bean实例会被销毁。
  • 应用场景: 与用户会话相关的数据存储,例如用户购物车。

5. Application

  • 描述: 在Web应用的整个ServletContext范围内共享一个Bean实例。
  • 特点 :
    • 所有请求和会话共享同一个Bean实例。
  • 应用场景: 应用级别的全局资源,例如配置或缓存。

6. WebSocket(在Spring 4.0+引入)

  • 描述: 为每个WebSocket会话创建一个Bean实例。
  • 特点 :
    • 在WebSocket连接的整个生命周期内共享。
  • 应用场景: WebSocket交互中需要保持的会话状态。

使用示例

在Spring配置中可以通过@Scope注解指定Bean的作用域:

java 复制代码
@Component
@Scope("prototype")  // 定义为原型作用域
public class MyBean {
    // Bean的实现
}

或者在XML配置中:

XML 复制代码
<bean id="myBean" class="com.example.MyBean" scope="prototype"/>

作用域总结

  • 单例原型可以在所有Spring应用中使用。
  • RequestSessionApplicationWebSocket作用域主要用于Web应用。
  • 选择作用域时应根据Bean的用途和生命周期要求来决定。

Bean的生命周期

在Spring中,Bean的生命周期是指一个Bean从创建到销毁的整个过程。Spring容器通过多种机制对Bean的生命周期进行管理,包括初始化、依赖注入以及销毁等。以下是Spring中Bean生命周期的主要阶段及相关机制:


1. Bean的定义和加载

  • Spring通过配置文件(XML、Java配置类)或注解(如@Component@Bean)定义Bean。
  • Spring容器在启动时解析这些定义,并将其加载为BeanDefinition对象。

2. Bean的实例化

  • Spring容器根据BeanDefinition创建Bean实例。
  • 使用Java反射机制或工厂方法来实例化对象。

3. 属性赋值(依赖注入)

  • Spring通过**依赖注入(DI, Dependency Injection)**将Bean的依赖项设置到其属性中。
  • 注入方式包括构造器注入、Setter注入或通过字段注入(使用@Autowired等注解)。

4. Bean初始化

Bean初始化阶段包括以下步骤:

  1. 执行Aware接口的方法 (如果实现了相关接口):
    • BeanNameAware: 注入Bean的名称。
    • BeanFactoryAware: 注入BeanFactory对象。
    • ApplicationContextAware: 注入ApplicationContext对象。
  2. 执行BeanPostProcessorpostProcessBeforeInitialization方法 :
    • 容器会调用所有已注册的BeanPostProcessorpostProcessBeforeInitialization方法,允许在初始化之前对Bean进行处理。
  3. 调用初始化方法 :
    • 如果实现了InitializingBean接口,调用其afterPropertiesSet()方法。
    • 如果配置了自定义的初始化方法(通过@Bean(initMethod = "methodName")或XML配置中的init-method),则执行该方法。
  4. 执行BeanPostProcessorpostProcessAfterInitialization方法 :
    • 容器会调用所有已注册的BeanPostProcessorpostProcessAfterInitialization方法,允许在初始化之后对Bean进行进一步处理。

5. Bean的使用

  • Bean已经完全初始化,可以被应用程序使用。
  • 在整个生命周期中,根据Bean的作用域,决定是单例共享还是按需创建。

6. Bean的销毁

当容器关闭时,Bean进入销毁阶段:

  1. 调用DisposableBean接口的destroy()方法(如果实现了该接口)。
  2. 执行自定义销毁方法 :
    • 如果配置了自定义销毁方法(通过@Bean(destroyMethod = "methodName")或XML配置中的destroy-method),则执行该方法。
  3. 释放资源 :
    • Spring容器释放与Bean相关的所有资源。

Bean生命周期示意图

  1. 定义和加载 →
  2. 实例化 →
  3. 属性赋值(依赖注入) →
  4. 初始化(Aware接口、BeanPostProcessor、初始化方法) →
  5. 使用 →
  6. 销毁(DisposableBean、自定义销毁方法)

示例代码

使用注解的生命周期管理
java 复制代码
@Component
public class MyBean implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() {
        System.out.println("InitializingBean: afterPropertiesSet called");
    }

    @Override
    public void destroy() {
        System.out.println("DisposableBean: destroy called");
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct: init method called");
    }

    @PreDestroy
    public void cleanup() {
        System.out.println("@PreDestroy: cleanup method called");
    }
}

总结

Spring中的Bean生命周期可以通过接口、注解和配置灵活管理,关键阶段包括实例化、依赖注入、初始化和销毁。开发者可以在这些阶段自定义行为,以满足特定需求,例如资源初始化和清理工作。

相关推荐
腻害兔10 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社11 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖12 小时前
JDK 26 新特性详解
java·开发语言
马优晨12 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
维天说15 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane199416 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
噢,我明白了16 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品16 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘17 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记17 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端