🌱 Spring Bean生命周期:从出生到死亡的完整旅程!

39 阅读7分钟

副标题:掌握Bean的一生,成为Spring高手!🎯


🎬 开场:Bean的一生

Bean的故事

一个Bean的自述:

大家好,我是一个Spring Bean 👋

我的一生经历了:
┌──────────────────────────────────┐
│  1. 出生(实例化)               │
│  2. 填充属性(依赖注入)         │
│  3. 初始化(各种回调)           │
│  4. 工作(被使用)               │
│  5. 销毁(清理资源)             │
└──────────────────────────────────┘

这个过程中,Spring提供了N个扩展点,
让你可以在我生命的各个阶段插手干预!

让我们一起来看看我这精彩的一生吧!🎭

📚 完整生命周期

生命周期总览

Spring Bean生命周期(11个步骤):

1️⃣  实例化(Instantiation)
    ↓
2️⃣  设置属性(Populate Properties)
    ↓
3️⃣  BeanNameAware.setBeanName()
    ↓
4️⃣  BeanFactoryAware.setBeanFactory()
    ↓
5️⃣  ApplicationContextAware.setApplicationContext()
    ↓
6️⃣  BeanPostProcessor.postProcessBeforeInitialization()
    ↓
7️⃣  @PostConstruct / InitializingBean.afterPropertiesSet()
    ↓
8️⃣  自定义init-method
    ↓
9️⃣  BeanPostProcessor.postProcessAfterInitialization()
    ↓
🔟  Bean ready for use(可以使用了)
    ↓
1️⃣1️⃣  @PreDestroy / DisposableBean.destroy() / destroy-method

🔍 详细步骤解析

步骤1:实例化(Instantiation)

/**
 * Bean的诞生!
 * 
 * Spring通过反射调用构造器创建Bean实例
 */
public class UserService {
    
    public UserService() {
        System.out.println("1️⃣ 构造器被调用,Bean实例化");
    }
}

// Spring内部:
Class<?> clazz = UserService.class;
Constructor<?> constructor = clazz.getConstructor();
Object bean = constructor.newInstance();  // 👶 Bean诞生了!

扩展点InstantiationAwareBeanPostProcessor

/**
 * 在实例化前后进行干预
 */
@Component
public class MyInstantiationAwareBeanPostProcessor 
    implements InstantiationAwareBeanPostProcessor {
    
    /**
     * 实例化之前调用
     * 
     * 可以返回代理对象,阻止默认实例化
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        System.out.println("1.1 实例化之前: " + beanName);
        
        // 返回null表示使用默认实例化
        return null;
    }
    
    /**
     * 实例化之后调用
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) {
        System.out.println("1.2 实例化之后: " + beanName);
        
        // 返回true表示继续后续处理
        return true;
    }
}

步骤2:设置属性(Populate Properties)

/**
 * Bean获得它的朋友们(依赖注入)
 */
@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;  // 注入依赖
    
    @Value("${app.name}")
    private String appName;  // 注入配置
    
    public UserService() {
        System.out.println("1️⃣ 构造器:userMapper = " + userMapper);  
        // 输出:null(还没注入)
    }
    
    @PostConstruct
    public void init() {
        System.out.println("7️⃣ 初始化:userMapper = " + userMapper);  
        // 输出:UserMapper实例(已注入)
    }
}

属性注入过程

Spring内部处理:

1. 扫描@Autowired@Resource@Value注解
2. 解析依赖
3. 从容器中查找依赖的Bean
4. 通过反射设置字段值

Field field = UserService.class.getDeclaredField("userMapper");
field.setAccessible(true);
field.set(userServiceInstance, userMapperInstance);

步骤3-5:Aware接口回调

/**
 * Bean认识自己和环境
 */
@Component
public class MyBean implements 
    BeanNameAware,           // 知道自己的名字
    BeanFactoryAware,        // 知道Bean工厂
    ApplicationContextAware  // 知道应用上下文
{
    
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;
    
    /**
     * 3️⃣ BeanNameAware:Bean知道自己叫什么
     */
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("3️⃣ 我知道我叫: " + name);
    }
    
    /**
     * 4️⃣ BeanFactoryAware:Bean知道自己的工厂
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
        System.out.println("4️⃣ 我知道我的工厂: " + beanFactory.getClass().getSimpleName());
    }
    
    /**
     * 5️⃣ ApplicationContextAware:Bean知道应用上下文
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        System.out.println("5️⃣ 我知道应用上下文: " + applicationContext.getClass().getSimpleName());
        
        // 现在可以从容器获取其他Bean了
        UserService userService = applicationContext.getBean(UserService.class);
    }
}

Aware接口家族

Spring提供的Aware接口:

BeanNameAware                → 获取Bean名称
BeanFactoryAware             → 获取BeanFactory
ApplicationContextAware      → 获取ApplicationContext
EnvironmentAware             → 获取Environment
ResourceLoaderAware          → 获取ResourceLoader
ApplicationEventPublisherAware → 获取事件发布器
MessageSourceAware           → 获取国际化资源
ServletContextAware          → 获取ServletContext(Web应用)

步骤6:BeanPostProcessor.postProcessBeforeInitialization()

/**
 * 初始化之前的扩展点
 * 
 * 这是最重要的扩展点之一!
 * Spring的很多功能都在这里实现:
 * - @Autowired注解处理
 * - @Value注解处理
 * - @PostConstruct注解处理
 * - AOP代理创建
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    /**
     * 6️⃣ 初始化之前
     * 
     * 可以修改Bean实例
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
        throws BeansException {
        
        System.out.println("6️⃣ 初始化之前: " + beanName);
        
        // 示例:给所有Bean添加创建时间
        if (bean instanceof BaseEntity) {
            ((BaseEntity) bean).setCreateTime(new Date());
        }
        
        return bean;
    }
    
    /**
     * 9️⃣ 初始化之后
     * 
     * 可以返回代理对象
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) 
        throws BeansException {
        
        System.out.println("9️⃣ 初始化之后: " + beanName);
        
        // 示例:创建AOP代理
        if (needProxy(bean)) {
            return createProxy(bean);
        }
        
        return bean;
    }
}

Spring内置的BeanPostProcessor

Spring内置了很多BeanPostProcessor:

1. CommonAnnotationBeanPostProcessor
   - 处理@PostConstruct
   - 处理@PreDestroy
   - 处理@Resource

2. AutowiredAnnotationBeanPostProcessor
   - 处理@Autowired
   - 处理@Value
   - 处理@Inject

3. ApplicationContextAwareProcessor
   - 处理各种Aware接口

4. AnnotationAwareAspectJAutoProxyCreator
   - 创建AOP代理

步骤7-8:初始化方法

/**
 * Bean的初始化
 * 
 * 三种方式,执行顺序:
 * 1. @PostConstruct
 * 2. InitializingBean.afterPropertiesSet()
 * 3. init-method
 */
@Component
public class UserService implements InitializingBean {
    
    @Autowired
    private UserMapper userMapper;
    
    /**
     * 7️⃣.1 @PostConstruct(推荐)
     * 
     * JSR-250标准注解
     */
    @PostConstruct
    public void postConstruct() {
        System.out.println("7️⃣.1 @PostConstruct执行");
        
        // 此时所有依赖都已注入
        System.out.println("userMapper已注入: " + (userMapper != null));
        
        // 可以做初始化工作
        loadCache();
    }
    
    /**
     * 7️⃣.2 InitializingBean.afterPropertiesSet()
     * 
     * Spring接口,不推荐(耦合Spring)
     */
    @Override
    public void afterPropertiesSet() {
        System.out.println("7️⃣.2 afterPropertiesSet()执行");
    }
    
    /**
     * 8️⃣ 自定义init-method
     * 
     * 通过@Bean(initMethod="init")指定
     */
    public void init() {
        System.out.println("8️⃣ 自定义init-method执行");
    }
    
    private void loadCache() {
        System.out.println("加载缓存数据...");
    }
}

// 配置类中指定init-method
@Configuration
public class AppConfig {
    
    @Bean(initMethod = "init")
    public UserService userService() {
        return new UserService();
    }
}

步骤9:BeanPostProcessor.postProcessAfterInitialization()

/**
 * 初始化之后的扩展点
 * 
 * AOP代理就是在这里创建的!
 */
@Component
public class AopProxyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        
        // 检查是否需要创建代理
        if (needAopProxy(bean)) {
            System.out.println("9️⃣ 为Bean创建AOP代理: " + beanName);
            
            // 创建JDK动态代理或CGLIB代理
            return Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) 
                        throws Throwable {
                        
                        System.out.println("代理方法执行: " + method.getName());
                        
                        // 执行原方法
                        return method.invoke(bean, args);
                    }
                }
            );
        }
        
        return bean;
    }
}

步骤10:Bean可以使用了

/**
 * 🔟 Bean已经完全初始化,可以使用了!
 */
@Service
public class OrderService {
    
    @Autowired
    private UserService userService;  // 已完全初始化的Bean
    
    public void createOrder() {
        // 使用Bean
        User user = userService.getUser(1L);
        
        // ...
    }
}

步骤11:销毁

/**
 * Bean的死亡
 * 
 * 三种方式,执行顺序:
 * 1. @PreDestroy
 * 2. DisposableBean.destroy()
 * 3. destroy-method
 */
@Component
public class UserService implements DisposableBean {
    
    /**
     * 1️⃣1️⃣.1 @PreDestroy(推荐)
     */
    @PreDestroy
    public void preDestroy() {
        System.out.println("1️⃣1️⃣.1 @PreDestroy执行");
        
        // 清理资源
        closeConnections();
    }
    
    /**
     * 1️⃣1️⃣.2 DisposableBean.destroy()
     */
    @Override
    public void destroy() {
        System.out.println("1️⃣1️⃣.2 destroy()执行");
    }
    
    /**
     * 1️⃣1️⃣.3 自定义destroy-method
     */
    public void cleanup() {
        System.out.println("1️⃣1️⃣.3 自定义destroy-method执行");
    }
    
    private void closeConnections() {
        System.out.println("关闭连接...");
    }
}

@Configuration
public class AppConfig {
    
    @Bean(destroyMethod = "cleanup")
    public UserService userService() {
        return new UserService();
    }
}

🎨 完整示例

示例代码

/**
 * 完整的Bean生命周期示例
 */
@Component
public class LifecycleBean implements 
    BeanNameAware, 
    BeanFactoryAware,
    ApplicationContextAware,
    InitializingBean,
    DisposableBean {
    
    private String beanName;
    
    @Autowired
    private UserService userService;
    
    // 1️⃣ 构造器
    public LifecycleBean() {
        System.out.println("1️⃣ 构造器执行");
    }
    
    // 2️⃣ 属性注入(在构造器之后)
    // Spring自动注入userService
    
    // 3️⃣ BeanNameAware
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("3️⃣ setBeanName: " + name);
    }
    
    // 4️⃣ BeanFactoryAware
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        System.out.println("4️⃣ setBeanFactory");
    }
    
    // 5️⃣ ApplicationContextAware
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        System.out.println("5️⃣ setApplicationContext");
    }
    
    // 6️⃣ BeanPostProcessor.postProcessBeforeInitialization()
    // (由BeanPostProcessor执行,不在Bean中)
    
    // 7️⃣.1 @PostConstruct
    @PostConstruct
    public void postConstruct() {
        System.out.println("7️⃣.1 @PostConstruct");
    }
    
    // 7️⃣.2 InitializingBean.afterPropertiesSet()
    @Override
    public void afterPropertiesSet() {
        System.out.println("7️⃣.2 afterPropertiesSet");
    }
    
    // 8️⃣ init-method(通过@Bean(initMethod="init")指定)
    public void init() {
        System.out.println("8️⃣ init-method");
    }
    
    // 9️⃣ BeanPostProcessor.postProcessAfterInitialization()
    // (由BeanPostProcessor执行,不在Bean中)
    
    // 🔟 Bean可以使用了
    
    // 1️⃣1️⃣.1 @PreDestroy
    @PreDestroy
    public void preDestroy() {
        System.out.println("1️⃣1️⃣.1 @PreDestroy");
    }
    
    // 1️⃣1️⃣.2 DisposableBean.destroy()
    @Override
    public void destroy() {
        System.out.println("1️⃣1️⃣.2 destroy");
    }
    
    // 1️⃣1️⃣.3 destroy-method(通过@Bean(destroyMethod="cleanup")指定)
    public void cleanup() {
        System.out.println("1️⃣1️⃣.3 destroy-method");
    }
}

运行结果

1️⃣ 构造器执行
1.1 实例化之前: lifecycleBean
1.2 实例化之后: lifecycleBean
2️⃣ 属性注入(自动)
3️⃣ setBeanName: lifecycleBean
4️⃣ setBeanFactory
5️⃣ setApplicationContext
6️⃣ postProcessBeforeInitialization: lifecycleBean
7️⃣.1 @PostConstruct
7️⃣.2 afterPropertiesSet
8️⃣ init-method
9️⃣ postProcessAfterInitialization: lifecycleBean
🔟 Bean可以使用了

--- 应用关闭 ---

1️⃣1️⃣.1 @PreDestroy
1️⃣1️⃣.2 destroy
1️⃣1️⃣.3 destroy-method

🎯 常见应用场景

场景1:初始化缓存

@Component
public class CacheService {
    
    private Map<String, Object> cache = new ConcurrentHashMap<>();
    
    /**
     * 应用启动时加载缓存
     */
    @PostConstruct
    public void initCache() {
        log.info("开始加载缓存...");
        
        // 从数据库加载数据
        List<Config> configs = configMapper.selectAll();
        
        for (Config config : configs) {
            cache.put(config.getKey(), config.getValue());
        }
        
        log.info("缓存加载完成,共{}条", cache.size());
    }
    
    /**
     * 应用关闭时清理缓存
     */
    @PreDestroy
    public void clearCache() {
        log.info("清理缓存...");
        cache.clear();
    }
}

场景2:数据库连接池

@Component
public class DataSourceManager implements DisposableBean {
    
    private DataSource dataSource;
    
    @PostConstruct
    public void initDataSource() {
        log.info("初始化数据源...");
        
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10);
        
        dataSource = new HikariDataSource(config);
        
        log.info("数据源初始化完成");
    }
    
    @Override
    public void destroy() {
        log.info("关闭数据源...");
        
        if (dataSource instanceof HikariDataSource) {
            ((HikariDataSource) dataSource).close();
        }
        
        log.info("数据源已关闭");
    }
}

场景3:定时任务初始化

@Component
public class ScheduledTaskManager {
    
    @Autowired
    private TaskScheduler taskScheduler;
    
    private ScheduledFuture<?> scheduledTask;
    
    @PostConstruct
    public void startScheduledTask() {
        log.info("启动定时任务...");
        
        scheduledTask = taskScheduler.scheduleAtFixedRate(() -> {
            log.info("执行定时任务");
            // 业务逻辑
        }, 60000);  // 每分钟执行一次
        
        log.info("定时任务已启动");
    }
    
    @PreDestroy
    public void stopScheduledTask() {
        log.info("停止定时任务...");
        
        if (scheduledTask != null) {
            scheduledTask.cancel(false);
        }
        
        log.info("定时任务已停止");
    }
}

🎉 总结

生命周期口诀

Bean生命周期要记牢,
十一个步骤不能少。

构造器里Bean诞生,
属性注入交朋友。
三个Aware知环境,
名字工厂和上下文。

前置处理做准备,
PostConstruct先执行。
afterPropertiesSet跟上,
自定义init最后到。

后置处理做代理,
AOP就在这里弄。
Bean准备好可以用,
工作一生为人民。

应用关闭要销毁,
PreDestroy先执行。
DisposableBean紧跟上,
destroy-method收尾好!

推荐实践

1. 初始化方法选择:
   推荐:@PostConstruct ⭐⭐⭐⭐⭐
   原因:标准、简单、不耦合Spring

2. 销毁方法选择:
   推荐:@PreDestroy ⭐⭐⭐⭐⭐
   原因:标准、简单、不耦合Spring

3. Aware接口:
   必要时使用:ApplicationContextAware
   不推荐:其他Aware(用@Autowired替代)

4. BeanPostProcessor:
   框架开发者使用
   应用开发者很少需要

关键扩展点

1. BeanPostProcessor
   - 最强大的扩展点
   - AOP、事务、校验都基于此

2. @PostConstruct / @PreDestroy
   - 最常用的扩展点
   - 初始化和清理资源

3. ApplicationContextAware
   - 获取ApplicationContext
   - 动态获取Bean

4. BeanFactoryPostProcessor
   - 修改BeanDefinition
   - 修改Bean配置元数据

愿你的Bean生命精彩,Spring之路一帆风顺! 🌱✨