说说bean的生命周期

5 阅读3分钟

Bean 生命周期是 Spring 容器的核心机制,从实例化 → 属性填充 → 初始化 → 使用 → 销毁,全程伴随扩展点供开发者介入。


一、完整生命周期流程图

┌─────────────────────────────────────────────────────────────────┐
│                         Spring 容器启动                           │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  1. 实例化(Instantiation)                                      │
│     └─► 反射调用构造方法 newInstance()                           │
│     └─► 此时:对象已创建,属性均为 null                           │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  2. 属性填充(Populate)                                         │
│     └─► 依赖注入 @Autowired / @Value / @Resource                │
│     └─► 处理 @AutowiredAnnotationBeanPostProcessor               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  3. 初始化前(Post-process before initialization)               │
│     └─► BeanPostProcessor.postProcessBeforeInitialization()      │
│     └─► @PostConstruct 执行点(InitDestroyAnnotationProcessor)   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  4. 初始化(Initialization)                                     │
│     └─► InitializingBean.afterPropertiesSet()                    │
│     └─► 自定义 init-method                                       │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  5. 初始化后(Post-process after initialization)                │
│     └─► BeanPostProcessor.postProcessAfterInitialization()       │
│     └─► AOP 代理在此创建(AbstractAutoProxyCreator)              │
│     └─► 返回的可能是 JDK 动态代理 / CGLIB 代理对象                 │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  6. Bean 就绪,存入单例池(Singleton Pool)                       │
│     └─► DefaultSingletonBeanRegistry.singletonObjects            │
│     └─► 供后续依赖注入使用                                        │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│  7. 容器关闭(Destruction)                                      │
│     └─► @PreDestroy 执行                                         │
│     └─► DisposableBean.destroy()                                 │
│     └─► 自定义 destroy-method                                    │
│     └─► 发布 ContextClosedEvent                                  │
└─────────────────────────────────────────────────────────────────┘

二、核心扩展点详解

1. Aware 接口(获取容器资源)

@Component
public class MyBean implements 
        BeanNameAware,           // 获取 beanName
        BeanFactoryAware,        // 获取 BeanFactory
        ApplicationContextAware, // 获取 ApplicationContext
        EnvironmentAware {       // 获取 Environment
    
    @Override
    public void setBeanName(String name) {
        System.out.println("① BeanNameAware: " + name);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        System.out.println("② ApplicationContextAware");
    }
}

执行时机:属性填充之后,初始化之前。


2. BeanPostProcessor(全局拦截器)

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String name) {
        // 初始化前:@PostConstruct 之前
        if (bean instanceof MyService) {
            System.out.println("Before init: " + name);
        }
        return bean; // 可返回代理对象替换原 bean
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String name) {
        // 初始化后:AOP 代理在此创建
        if (bean instanceof MyService) {
            // 创建代理,实现切面逻辑
            return Proxy.newProxyInstance(...);
        }
        return bean;
    }
}

经典应用:AOP、事务注解解析、@Async 代理创建。


3. 生命周期注解(JSR-250)

@Component
public class OrderService {
    
    @PostConstruct
    public void init() {
        // 依赖注入完成后执行
        // 用途:缓存预热、连接初始化、配置校验
        System.out.println("③ @PostConstruct");
    }
    
    @PreDestroy
    public void destroy() {
        // 容器关闭前执行
        // 用途:释放连接、保存状态、清理资源
        System.out.println("⑦ @PreDestroy");
    }
}

优先级:@PostConstruct > InitializingBean > init-method


4. InitializingBean / DisposableBean

@Component
public class PaymentService implements InitializingBean, DisposableBean {
    
    @Override
    public void afterPropertiesSet() throws Exception {
        // 属性设置后,@PostConstruct 之后
        System.out.println("④ InitializingBean");
    }
    
    @Override
    public void destroy() throws Exception {
        // 容器销毁时,@PreDestroy 之后
        System.out.println("⑥ DisposableBean");
    }
}

三、完整执行顺序验证

@Component
public class LifecycleDemo implements 
        BeanNameAware, InitializingBean, DisposableBean {
    
    public LifecycleDemo() {
        System.out.println("1. 构造方法(实例化)");
    }
    
    @Autowired
    public void setDependency(Dependency dep) {
        System.out.println("2. 依赖注入(属性填充)");
    }
    
    @Override
    public void setBeanName(String name) {
        System.out.println("3. BeanNameAware");
    }
    
    @PostConstruct
    public void postConstruct() {
        System.out.println("4. @PostConstruct");
    }
    
    @Override
    public void afterPropertiesSet() {
        System.out.println("5. InitializingBean");
    }
    
    public void customInit() {
        System.out.println("6. init-method");
    }
    
    @PreDestroy
    public void preDestroy() {
        System.out.println("7. @PreDestroy");
    }
    
    @Override
    public void destroy() {
        System.out.println("8. DisposableBean");
    }
    
    public void customDestroy() {
        System.out.println("9. destroy-method");
    }
}

输出结果

1. 构造方法(实例化)
2. 依赖注入(属性填充)
3. BeanNameAware
4. @PostConstruct
5. InitializingBean
6. init-method
[Bean 就绪,进入使用期]
7. @PreDestroy
8. DisposableBean
9. destroy-method

四、面试核心答法

"Bean 生命周期分五个阶段:实例化(构造方法)→ 属性填充(依赖注入)→ 初始化(Aware → @PostConstruct → InitializingBean → init-method → BeanPostProcessor 代理创建)→ 使用(单例池)→ 销毁(@PreDestroy → DisposableBean → destroy-method)。扩展点主要有 BeanPostProcessor(AOP 核心)、Aware 接口(获取容器资源)、生命周期注解。Spring 的 AOP 代理就是在初始化后的 postProcessAfterInitialization 中创建的。"

加分点

  • 提到 BeanPostProcessor 是 Spring AOP 的底层机制
  • 说明 @PostConstruct 比 InitializingBean 更推荐(解耦 Spring 接口)
  • 解释 为什么构造方法不能用 @Value(此时属性尚未注入)