Bean作用域与生命周期管理
2025/9/17大约 7 分钟
Spring Bean作用域与生命周期管理
本文将深入探讨Spring框架中Bean的作用域管理、生命周期控制以及多种实例化方式,帮助你全面掌握Spring容器的核心机制。
Bean作用域详解
什么是Bean作用域
Bean作用域决定了Spring容器如何创建和管理Bean实例。Spring提供了多种作用域来满足不同的业务需求。
作用域类型
Spring主要提供以下作用域:
- singleton:单例模式(默认)
- prototype:原型模式
- request:请求作用域(Web环境)
- session:会话作用域(Web环境)
- application:应用作用域(Web环境)
singleton作用域
singleton是Spring的默认作用域,整个容器中只会创建一个Bean实例。
@Data
public class UserService {
private String serviceName;
public UserService() {
System.out.println("UserService实例被创建: " + this.hashCode());
}
}
<!-- 默认就是singleton作用域 -->
<bean id="userService" class="com.example.service.UserService" scope="singleton">
<property name="serviceName" value="用户服务"/>
</bean>
测试singleton作用域
@Test
public void testSingleton() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 多次获取Bean,验证是否为同一实例
UserService service1 = context.getBean("userService", UserService.class);
UserService service2 = context.getBean("userService", UserService.class);
System.out.println("service1: " + service1.hashCode());
System.out.println("service2: " + service2.hashCode());
System.out.println("是否为同一实例: " + (service1 == service2)); // true
}
singleton特点
- 容器启动时创建实例
- 全局共享同一实例
- 线程不安全(需要注意状态管理)
- 适合无状态的服务类
prototype作用域
prototype作用域每次请求都会创建新的Bean实例。
<bean id="userService" class="com.example.service.UserService" scope="prototype">
<property name="serviceName" value="用户服务"/>
</bean>
测试prototype作用域
@Test
public void testPrototype() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService service1 = context.getBean("userService", UserService.class);
UserService service2 = context.getBean("userService", UserService.class);
System.out.println("service1: " + service1.hashCode());
System.out.println("service2: " + service2.hashCode());
System.out.println("是否为不同实例: " + (service1 != service2)); // true
}
prototype注意事项
- 每次getBean()都创建新实例
- Spring不管理prototype Bean的完整生命周期
- 销毁方法不会被自动调用
- 适合有状态的Bean
工厂模式在Spring中的应用
简单工厂模式
Spring的BeanFactory就是简单工厂模式的典型应用。
// 产品接口
public interface Weapon {
void attack();
}
// 具体产品
public class Gun implements Weapon {
@Override
public void attack() {
System.out.println("开枪射击!");
}
}
public class Sword implements Weapon {
@Override
public void attack() {
System.out.println("挥剑攻击!");
}
}
// 简单工厂
public class WeaponFactory {
public static Weapon createWeapon(String type) {
switch (type.toUpperCase()) {
case "GUN":
return new Gun();
case "SWORD":
return new Sword();
default:
throw new IllegalArgumentException("未知武器类型: " + type);
}
}
}
工厂方法模式
工厂方法模式解决了简单工厂模式的扩展性问题。
工厂方法模式实现
// 抽象工厂
public interface WeaponFactory {
Weapon createWeapon();
}
// 具体工厂
public class GunFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
return new Gun();
}
}
public class SwordFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
return new Sword();
}
}
// 客户端使用
@Test
public void testFactoryMethod() {
WeaponFactory gunFactory = new GunFactory();
Weapon gun = gunFactory.createWeapon();
gun.attack();
WeaponFactory swordFactory = new SwordFactory();
Weapon sword = swordFactory.createWeapon();
sword.attack();
}
Bean实例化方式
Spring提供了多种Bean实例化方式,以满足不同的创建需求。
1. 构造方法实例化
这是最常用的方式,Spring调用Bean的无参构造方法。
@Data
@NoArgsConstructor
public class User {
private String name;
private Integer age;
public User() {
System.out.println("User构造方法被调用");
}
}
<bean id="user" class="com.example.bean.User">
<property name="name" value="张三"/>
<property name="age" value="25"/>
</bean>
2. 静态工厂方法实例化
通过静态工厂方法创建Bean实例。
public class UserFactory {
public static User createUser() {
System.out.println("通过静态工厂方法创建User");
User user = new User();
user.setName("工厂用户");
return user;
}
}
<!-- 使用factory-method指定静态工厂方法 -->
<bean id="user" class="com.example.factory.UserFactory" factory-method="createUser"/>
3. 实例工厂方法实例化
通过工厂Bean的实例方法创建目标Bean。
public class UserFactory {
public User createUser() {
System.out.println("通过实例工厂方法创建User");
User user = new User();
user.setName("实例工厂用户");
return user;
}
}
<!-- 先创建工厂Bean -->
<bean id="userFactory" class="com.example.factory.UserFactory"/>
<!-- 通过工厂Bean创建目标Bean -->
<bean id="user" factory-bean="userFactory" factory-method="createUser"/>
4. FactoryBean接口实例化
FactoryBean是Spring提供的特殊接口,用于创建复杂的Bean。
@Component
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
// 复杂的创建逻辑
User user = new User();
user.setName("FactoryBean用户");
user.setAge(30);
return user;
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
return true; // 返回单例
}
}
<bean id="user" class="com.example.factory.UserFactoryBean"/>
FactoryBean vs BeanFactory
- BeanFactory:Spring IoC容器的顶级接口,是Bean工厂
- FactoryBean:特殊的Bean,用于辅助Spring创建其他Bean
Bean生命周期管理
生命周期概述
Bean的生命周期是指从创建到销毁的整个过程,了解生命周期有助于在合适的时机执行特定逻辑。
5步生命周期
基本的Bean生命周期包含5个步骤:
- 实例化Bean
- 设置Bean属性
- 初始化Bean
- 使用Bean
- 销毁Bean
@Data
public class LifecycleBean {
private String name;
public LifecycleBean() {
System.out.println("1. 实例化Bean");
}
public void setName(String name) {
this.name = name;
System.out.println("2. 设置Bean属性: " + name);
}
// 初始化方法
public void initMethod() {
System.out.println("3. 初始化Bean");
}
// 销毁方法
public void destroyMethod() {
System.out.println("5. 销毁Bean");
}
}
<bean id="lifecycleBean"
class="com.example.bean.LifecycleBean"
init-method="initMethod"
destroy-method="destroyMethod">
<property name="name" value="生命周期测试"/>
</bean>
测试生命周期
@Test
public void testLifecycle() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
LifecycleBean bean = context.getBean("lifecycleBean", LifecycleBean.class);
System.out.println("4. 使用Bean: " + bean.getName());
// 关闭容器,触发销毁方法
context.close();
}
7步生命周期(含BeanPostProcessor)
通过添加Bean后处理器,可以在初始化前后执行自定义逻辑。
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println("Bean后处理器:初始化前处理");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println("Bean后处理器:初始化后处理");
}
return bean;
}
}
<!-- 注册Bean后处理器 -->
<bean class="com.example.processor.CustomBeanPostProcessor"/>
完整生命周期(10步)

完整生命周期实现
@Data
public class CompleteLifecycleBean implements
BeanNameAware, BeanFactoryAware, BeanClassLoaderAware,
InitializingBean, DisposableBean {
private String name;
public CompleteLifecycleBean() {
System.out.println("1. 实例化Bean");
}
public void setName(String name) {
this.name = name;
System.out.println("2. 设置Bean属性");
}
@Override
public void setBeanName(String name) {
System.out.println("3. 设置Bean名称: " + name);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("3. 设置类加载器: " + classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3. 设置Bean工厂: " + beanFactory);
}
// BeanPostProcessor的before方法在此处被调用
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5. InitializingBean.afterPropertiesSet()");
}
public void customInit() {
System.out.println("6. 自定义初始化方法");
}
// BeanPostProcessor的after方法在此处被调用
@Override
public void destroy() throws Exception {
System.out.println("9. DisposableBean.destroy()");
}
public void customDestroy() {
System.out.println("10. 自定义销毁方法");
}
}
作用域对生命周期的影响
重要提醒
- singleton:Spring管理完整生命周期,包括销毁
- prototype:Spring只负责创建,不管理销毁过程
<!-- prototype作用域的Bean不会执行销毁方法 -->
<bean id="prototypeBean"
class="com.example.bean.LifecycleBean"
scope="prototype"
init-method="initMethod"
destroy-method="destroyMethod">
<property name="name" value="原型Bean"/>
</bean>
实际应用场景
配置数据源
@Data
public class DataSource {
private String url;
private String username;
private String password;
public void init() {
System.out.println("数据源初始化,建立连接池");
// 初始化连接池逻辑
}
public void destroy() {
System.out.println("数据源销毁,关闭连接池");
// 关闭连接池逻辑
}
}
<bean id="dataSource"
class="com.example.config.DataSource"
init-method="init"
destroy-method="destroy">
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
缓存管理
@Component
public class CacheManager implements InitializingBean, DisposableBean {
private Map<String, Object> cache = new ConcurrentHashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("缓存管理器初始化");
// 预加载缓存数据
}
@Override
public void destroy() throws Exception {
System.out.println("缓存管理器销毁,清理缓存");
cache.clear();
}
public void put(String key, Object value) {
cache.put(key, value);
}
public Object get(String key) {
return cache.get(key);
}
}
最佳实践
1. 选择合适的作用域
// 无状态服务类 - 使用singleton
@Service
@Scope("singleton") // 默认值,可省略
public class UserService {
// 无状态逻辑
}
// 有状态的工具类 - 使用prototype
@Component
@Scope("prototype")
public class ReportGenerator {
private List<String> data = new ArrayList<>();
// 有状态逻辑
}
2. 合理使用生命周期回调
@Component
public class ResourceManager implements InitializingBean, DisposableBean {
private ExecutorService executor;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化资源
executor = Executors.newFixedThreadPool(10);
System.out.println("线程池初始化完成");
}
@Override
public void destroy() throws Exception {
// 清理资源
if (executor != null && !executor.isShutdown()) {
executor.shutdown();
System.out.println("线程池已关闭");
}
}
}
3. 使用@PostConstruct和@PreDestroy
@Component
public class ModernLifecycleBean {
@PostConstruct
public void init() {
System.out.println("使用@PostConstruct初始化");
}
@PreDestroy
public void cleanup() {
System.out.println("使用@PreDestroy清理资源");
}
}
总结
本文详细介绍了Spring Bean的作用域管理和生命周期控制:
- 作用域管理:掌握singleton和prototype的区别和使用场景
- 工厂模式:理解Spring中工厂模式的应用
- 实例化方式:学会多种Bean创建方式的使用
- 生命周期:了解Bean从创建到销毁的完整过程
- 最佳实践:在实际项目中合理选择和使用
通过合理使用这些特性,可以更好地管理应用中的对象生命周期,提高系统的可维护性和性能。
下一步学习
接下来我们将学习Spring的循环依赖问题和解决方案,以及基于注解的配置方式。