欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > Bean 生命周期与作用域:从创建到销毁的完整掌控

Bean 生命周期与作用域:从创建到销毁的完整掌控

2025/11/11 8:14:27 来源:https://blog.csdn.net/weixin_46619605/article/details/147272170  浏览:    关键词:Bean 生命周期与作用域:从创建到销毁的完整掌控

在 Spring 应用中,Bean 的生命周期和作用域是对象管理的核心机制。

它们决定了Bean 的创建方式、存活时间以及作用范围。深入理解这些机制,可以避免内存泄漏、优化资源利用,并设计出更高效的 Spring 应用。

一、Bean 的生命周期:从诞生到消亡

SpringBean 的生命周期是指从Bean 创建到销毁的完整过程。Spring 提供了多种方式来管理 Bean 的生命周期,包括初始化方法、销毁方法、生命周期回调接口等。

1.1 生命周期流程图

实例化 → 属性注入 → 初始化 → 使用中 → 销毁

1.实例化(Instantiation)

Spring 容器创建 Bean 的实例。

2.属性赋值(Populate Properties)

Spring 容器根据配置文件或注解,为 Bean 注入依赖。

3.初始化(Initialization)

在 Bean 可用之前,Spring 会执行初始化操作(可通过@PostConstruct、InitializingBean或init-method实现)。

4.使用(Usage)

Bean 处于运行状态,可供应用程序调用和使用。

5.销毁(Destruction)

当容器关闭时,Spring 会执行销毁回调(可通过@PreDestroy、DisposableBean或destroy-method实现)。

1.2 初始化与销毁的三种方式

方式 1:注解驱动(推荐)

通过@PostConstruct和@PreDestroy管理生命周期。

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;@Component // 该类被 Spring 作为 Bean 进行管理
public class DatabaseConnector {@PostConstructpublic void connect() {System.out.println("数据库连接已建立");}@PreDestroypublic void disconnect() {System.out.println("数据库连接已关闭");}
}

注解说明

• @Component

声明该类为 Spring 管理的 Bean。

• @PostConstruct

在 Bean 初始化后自动执行。

• @PreDestroy

在 Bean 销毁前执行。

优势

• 代码简洁,无侵入性。

• 无需实现特定接口。

方式 2:实现 Spring 接口

通过InitializingBean和DisposableBean接口管理生命周期。

Spring 提供了InitializingBean(初始化)和DisposableBean(销毁)两个接口,它们分别包含:

• afterPropertiesSet()

• destroy()

示例:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
public class MyBean implements InitializingBean, DisposableBean {public MyBean() {System.out.println("1. Bean 实例化");}@Overridepublic void afterPropertiesSet() {System.out.println("2. Bean 初始化(afterPropertiesSet)");}@Overridepublic void destroy() {System.out.println("3. Bean 销毁(destroy)");}
}

注解/接口说明

• InitializingBean接口:提供afterPropertiesSet()方法,Spring 在 Bean 初始化后调用。

• DisposableBean接口:提供destroy()方法,Spring 在 Bean 销毁前调用。

适用场景

• 需要与 Spring 早期版本兼容。

• 明确的生命周期方法定义。

方式 3:XML/Java 显式配置

通过init-method和destroy-method指定初始化和销毁方法。

在@Bean方法或 XML 配置中,也可以手动指定初始化和销毁方法:

@Configuration
public class AppConfig {@Bean(initMethod = "init", destroyMethod = "cleanup")public FileProcessor fileProcessor() {return new FileProcessor();}
}public class FileProcessor {public void init() {System.out.println("文件处理器初始化完成");}public void cleanup() {System.out.println("临时文件已清理");}
}

所用配置

• initMethod=“init”:指定初始化方法,在 Bean 创建后调用。

• destroyMethod=“cleanup”:指定销毁方法,在 Bean 销毁前调用。

适用场景

• 无法修改第三方库的源码。

• 需要动态指定初始化逻辑。

二、Bean 的作用域:控制对象的作用范围

Spring 支持6 种作用域,其中4 种专为 Web 应用设计。最常用的作用域是Singleton和Prototype。

2.1 核心作用域详解

1. Singleton(单例)

特点:

• 默认作用域。

• 适用于无状态 Bean(如 Service、DAO)。

• 容器启动时创建(可配置懒加载)。

• 全局唯一,整个 Spring 容器中只有一个 Bean 实例。

示例:

import org.springframework.stereotype.Component;@Component // 默认作用域是 Singleton
public class SingletonBean {public SingletonBean() {System.out.println("SingletonBean 被创建");}
}

验证单例作用域

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SingletonBean bean1 = context.getBean(SingletonBean.class);
SingletonBean bean2 = context.getBean(SingletonBean.class);System.out.println(bean1 == bean2);  // true

说明

• @Component 将类声明为 Spring Bean。

• 默认作用域是Singleton,即整个容器中只有一个实例。

2. Prototype(原型作用域,每次获取都创建新实例)

特点:

• 每次获取getBean(),都会创建一个新实例。

• 适用于有状态的 Bean,如需要频繁创建的新对象,如DTO、会话上下文。

示例:

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;@Component
@Scope("prototype") // 设置为 Prototype 作用域,每次获取都会创建新实例
public class PrototypeBean {public PrototypeBean() {System.out.println("PrototypeBean 被创建");}
}

验证 Prototype 作用域

PrototypeBean bean1 = context.getBean(PrototypeBean.class);
PrototypeBean bean2 = context.getBean(PrototypeBean.class);System.out.println(bean1 == bean2);  // false

注解说明

• @Scope(“prototype”)

每次获取 Bean 时,Spring 都会创建新实例。

3. Web 作用域
在这里插入图片描述

示例 request 作用域:

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;@Component
@Scope("request") // 作用域设置为 request,每个请求都会创建新 Bean
public class RequestScopedBean {public RequestScopedBean() {System.out.println("RequestScopedBean 被创建");}
}

注解说明

• @Scope(“request”)

每个 HTTP 请求都会创建新的 Bean 实例,适用于 Web 应用。

2.2 作用域配置陷阱与解决方案

问题:

单例 Bean 注入原型 Bean 时,原型失效。

原因:

单例 Bean 初始化时已固定依赖的原型实例。

解决方案

• 使用方法注入(@Lookup)。

• 通过ObjectFactory延迟获取。

• 设置代理模式(proxyMode = ScopedProxyMode.TARGET_CLASS)。

@Service
public class OrderService {@Autowiredprivate ObjectFactory<ShoppingCart> cartFactory;public void checkout() {ShoppingCart cart = cartFactory.getObject(); // 每次获取新实例// ...}
}

三、实战:生命周期与作用域的综合应用

场景:数据库连接池管理

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ConnectionPool {private List<Connection> connections;@PostConstructpublic void init() {System.out.println("初始化连接池...");connections = Collections.synchronizedList(new ArrayList<>());// 创建初始连接}public Connection getConnection() {return connections.remove(0);}@PreDestroypublic void destroy() {System.out.println("关闭所有连接...");connections.forEach(Connection::close);}
}

设计要点

• 单例作用域管理共享资源

• 初始化时建立连接池

• 销毁时安全释放资源

四、总结与进阶

4.1 关键知识点回顾

• 生命周期管理:通过注解、接口、配置三种方式控制 Bean 的初始化和销毁

• 作用域选择:根据对象状态和使用场景选择合适的作用域

• Web 作用域:合理使用Request/Session作用域处理 Web 层数据

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词