Skip to content

Spring Bean 生命周期管理完整指南

目录

  1. 概述
  2. Bean 生命周期的完整流程
  3. 阶段一:BeanDefinition 加载与处理
  4. 阶段二:BeanFactoryPostProcessor 处理
  5. 阶段三:Bean 实例化
  6. 阶段四:属性填充
  7. 阶段五:Aware 接口回调
  8. 阶段六:初始化前处理
  9. 阶段七:初始化回调
  10. 阶段八:初始化后处理
  11. 阶段九:Bean 就绪使用
  12. 阶段十:销毁回调
  13. BeanPostProcessor 深度解析
  14. InstantiationAwareBeanPostProcessor 详解
  15. BeanFactoryPostProcessor 详解
  16. Bean 作用域(Scope)
  17. 循环依赖处理
  18. 延迟加载机制
  19. SmartInitializingSingleton 回调
  20. 最佳实践与注意事项

概述

Spring Bean 的生命周期是 Spring 框架最核心、最复杂的机制之一。理解 Bean 的生命周期对于掌握 Spring 的依赖注入、AOP 代理、自定义扩展点等高级特性至关重要。

为什么需要理解 Bean 生命周期?

  • 调试问题:许多 Spring 相关问题的根源在于对生命周期理解不足
  • 自定义扩展:通过实现各种处理器接口,可以定制 Bean 的创建和行为
  • AOP 原理:Spring AOP 基于 BeanPostProcessor 在生命周期中创建代理
  • 性能优化:理解何时创建 Bean 有助于优化应用启动时间

Bean 生命周期的完整流程

┌─────────────────────────────────────────────────────────────────────────┐
│                        Spring Bean 生命周期全流程                         │
└─────────────────────────────────────────────────────────────────────────┘

1. 【BeanDefinition 扫描】容器启动,扫描@Component、@Configuration 等注解

2. 【BeanDefinition 注册】将组件信息封装为 BeanDefinition,注册到 BeanDefinitionRegistry

3. 【BeanFactoryPostProcessor】执行所有 BeanFactoryPostProcessor.postProcessBeanFactory()
   - 此时 Bean 还未实例化,可修改 BeanDefinition

4. 【预实例化处理】InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
   - 可提前返回自定义对象,跳过后续步骤

5. 【Bean 实例化】通过构造函数/工厂方法创建 Bean 原始实例

6. 【实例化后处理】InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
   - 返回 false 可跳过属性填充

7. 【缓存早期引用】单例 Bean 的早期引用放入三级缓存(用于循环依赖解决)

8. 【属性填充准备】InstantiationAwareBeanPostProcessor.postProcessProperties()

9. 【属性注入】Autowired、@Value 等依赖注入

10. 【BeanNameAware】setBeanName() 回调

11. 【BeanFactoryAware】setBeanFactory() 回调

12. 【ApplicationContextAware】setApplicationContext() 回调

13. 【其他 Aware 接口】ResourceLoaderAware、EnvironmentAware 等

14. 【BeanPostProcessor.beforeInitialization】postProcessBeforeInitialization()
    - 所有注册的 BeanPostProcessor 依次执行

15. 【@PostConstruct】执行 JSR-250 标准的初始化方法

16. 【InitializingBean】afterPropertiesSet() 回调

17. 【自定义 init-method】配置文件中指定的初始化方法

18. 【BeanPostProcessor.afterInitialization】postProcessAfterInitialization()
    - AOP 代理在此处创建!所有 BeanPostProcessor 依次执行

19. 【单例注册完成】Bean 放入 singletonObjects 缓存,可供其他 Bean 使用

20. 【SmartInitializingSingleton】all singleton beans instantiated after...
     - 所有单例 Bean 创建完成后调用

21. 【Container Ready】容器启动完成,Bean 可以使用

... 应用运行 ...

22. 【@PreDestroy】容器关闭时执行

23. 【DisposableBean】destroy() 回调

24. 【自定义 destroy-method】配置文件中指定的销毁方法

25. 【Bean 销毁完成】

阶段一:BeanDefinition 加载与处理

1.1 BeanDefinition 的作用

BeanDefinition 是 Spring 对 Bean 的元数据描述,包含了创建 Bean 所需的所有信息:

java
public interface BeanDefinition {
    // Bean 的类名
    String getBeanClassName() throws CannotLoadBeanClassException;

    // 父 BeanDefinition
    String getParentName();

    // Bean 的作用域
    String getScope();

    // 是否懒加载
    boolean isLazyInit();

    // 初始化方法
    String getInitMethodName();

    // 销毁方法
    String getDestroyMethodName();

    // 是否单例
    boolean isSingleton();

    // 抽象定义
    boolean isAbstract();
}

1.2 BeanDefinition 的来源

来源说明
XML 配置<bean id="..." class="...">
Java Config@Bean 注解方法
组件扫描@Component@Service@Repository@Controller
@Import导入的配置类
@ComponentScan自动扫描包下的组件
手动注册registry.registerBeanDefinition()

1.3 典型 BeanDefinition 实现

java
// 最常用的实现类
class GenericBeanDefinition implements BeanDefinition {
    private String beanClassName;
    private String scope;
    private boolean lazyInit = false;
    private String initMethodName;
    private String destroyMethodName;
    private Map<String, Object> attributeMap;
    // ...
}

阶段二:BeanFactoryPostProcessor 处理

2.1 BeanFactoryPostProcessor 的作用时机

BeanFactoryPostProcessor 在所有 BeanDefinition 加载完成后、任何 Bean 实例化之前执行。这是修改 BeanDefinition 的最后机会。

java
public interface BeanFactoryPostProcessor {
    /**
     * 在后端 BeanDefinition 已加载但尚未实例化之前进行后置处理
     * @param beanFactory 可配置的 ListableBeanFactory
     * @throws BeansException 如果处理失败
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

2.2 典型应用场景

java
// 1. PropertySourcesPlaceholderConfigurer - 占位符解析
@Configuration
public class PlaceholderConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

// 2. 自定义 BeanFactoryPostProcessor
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 获取所有 BeanDefinition
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            // 修改 BeanDefinition
            bd.setLazyInit(true);
        }
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE; // 优先级越高,order 值越小
    }
}

2.3 BeanDefinitionRegistryPostProcessor

更强大的变体,可以注册新的 BeanDefinition:

java
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    /**
     * 在后端 BeanDefinition 已加载后,但标准 Spring 容器创建之前
     * 可以对 BeanDefinitionRegistry 进行后置处理
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

重要实现:

  • ConfigurationClassPostProcessor - 处理@Configuration 和组件扫描
  • ComponentScanAnnotationParser - 解析@ComponentScan

2.4 Spring Boot 内置的 BeanFactoryPostProcessor

java
// LazyInitializationBeanFactoryPostProcessor - 延迟初始化
// 设置未被明确排除且未显式设置 lazy-init 的 BeanDefinition 为懒加载
public class LazyInitializationBeanFactoryPostProcessor
        implements BeanFactoryPostProcessor, Ordered {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
            if (!isExcluded(bd)) {
                bd.setLazyInit(true);
            }
        }
    }
}

阶段三:Bean 实例化

3.1 实例化前的拦截:postProcessBeforeInstantiation

java
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * 在 Bean 实例化之前调用
     * 返回值非 null 时,Spring 会使用返回的对象作为 Bean 实例
     * 跳过后续的实例化和属性填充步骤
     */
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        return null;
    }
}

应用场景:

  • CGLIB 代理的准备工作
  • 自定义对象的替换逻辑
  • MyBatis 的 MapperFactoryBean 使用此机制

3.2 实例化方式

Spring 支持多种 Bean 实例化方式:

java
// 1. 默认构造函数(最常用)
@Bean
public Service service() {
    return new Service();
}

// 2. 静态工厂方法
@Bean
public Service serviceFromStaticFactory() {
    return Factory.createService();
}

// 3. 实例工厂方法
@Bean
public Factory factory() {
    return new Factory();
}

@Bean
public Service serviceFromInstanceFactory(Factory factory) {
    return factory.createService();
}

// 4. 普通工厂方法(配置类中的 Bean 方法)
@Configuration
public class AppConfig {
    @Bean
    public Service service() {
        return new Service();
    }
}

3.3 构造器注入与实例化

java
@Service
public class UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;

    // Spring 4.3+:只有一个构造器时,@Autowired 可选
    public UserService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }
}

// Spring 4.3- 或多个构造器时需要明确标注
@Service
public class OrderService {
    private final PaymentService paymentService;

    @Autowired  // 指定使用此构造器
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public OrderService() {
        // 无参构造器,不会被使用
    }
}

3.4 实例化后的拦截:postProcessAfterInstantiation

java
default boolean postProcessAfterInstantiation(Object bean, String beanName) {
    // 返回 true:继续属性填充
    // 返回 false:跳过属性填充和 Aware 回调
    return true;
}

阶段四:属性填充

4.1 属性填充前处理:postProcessProperties

java
default PropertyValues postProcessProperties(
        PropertyValues pvs,
        ReflectionData beanInfo,
        String beanName) {
    // 可以修改或添加属性值
    return pvs;
}

4.2 依赖注入类型

@Autowired 注入

java
@Service
public class OrderService {

    // 字段注入(不推荐,但最常见)
    @Autowired
    private PaymentService paymentService;

    // 构造器注入(推荐,不可变、易于测试)
    private final InventoryService inventoryService;

    @Autowired
    public OrderService(InventoryService inventoryService) {
        this.inventoryService = inventoryService;
    }

    // Setter 注入(适用于可选依赖)
    private NotificationService notificationService;

    @Autowired(required = false)
    public void setNotificationService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
}

@Resource 注入(JSR-250)

java
@Resource  // 默认按名称查找
private PaymentService paymentService;

@Resource(name = "specificPaymentService")  // 指定名称
private PaymentService specificPaymentService;

@Inject 注入(JSR-330)

java
@Inject
private PaymentService paymentService;

// 配合 Qualifier 使用
@Inject
@Qualifier("alipayService")
private PaymentService paymentService;

4.3 集合注入

java
@Service
public class ReportService {

    // 注入所有 Reporter 实现的 List
    @Autowired
    private List<Reporter> reporters;

    // 注入所有 Reporter 实现的 Set
    @Autowired
    private Set<Reporter> reporterSet;

    // 注入所有 Reporter 实现的 Map(key 为 bean 名称)
    @Autowired
    private Map<String, Reporter> reporterMap;
}

4.4 @Value 注解

java
@Component
public class AppConfig {

    // 简单值
    @Value("${app.name}")
    private String appName;

    // SpEL 表达式
    @Value("#{systemProperties['user.home']}")
    private String userHome;

    // SpEL 引用 Bean
    @Value("#{userService}")
    private UserService userService;
}

阶段五:Aware 接口回调

Aware 接口允许 Bean 感知 Spring 容器的存在,并获取容器中的资源。

5.1 核心 Aware 接口

java
// 1. BeanNameAware - 获取 Bean 的名称
@Component
public class MyBean implements BeanNameAware {
    @Override
    public void setBeanName(String name) {
        System.out.println("Bean name: " + name);
    }
}

// 2. BeanFactoryAware - 获取 BeanFactory
@Component
public class MyBean implements BeanFactoryAware {
    private AutowireCapableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
    }
}

// 3. ApplicationContextAware - 获取 ApplicationContext(最常用)
@Component
public class MyBean implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        this.applicationContext = context;
    }
}

5.2 其他 Aware 接口

java
// ResourceLoaderAware - 资源加载器
public class MyBean implements ResourceLoaderAware {
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        Resource resource = resourceLoader.getResource("classpath:config.txt");
    }
}

// ApplicationEventPublisherAware - 事件发布器
public class MyBean implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void doSomething() {
        publisher.publishEvent(new CustomEvent(this));
    }
}

// MessageSourceAware - 消息源(国际化)
public class MyBean implements MessageSourceAware {
    @Override
    public void setMessageSource(MessageSource messageSource) {
        String msg = messageSource.getMessage("greeting", null, Locale.US);
    }
}

// EnvironmentAware - 环境信息
public class MyBean implements EnvironmentAware {
    @Override
    public void setEnvironment(Environment env) {
        String activeProfile = env.getActiveProfiles()[0];
        boolean hasProperty = env.containsProperty("db.url");
    }
}

// EmbeddedValueResolverAware - 占位符解析
public class MyBean implements EmbeddedValueResolverAware {
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String resolved = resolver.resolveStringValue("${app.name}");
    }
}

5.3 Aware 接口的执行顺序

1. BeanNameAware.setBeanName()
2. BeanClassLoaderAware.setBeanClassLoader()
3. BeanFactoryAware.setBeanFactory()
4. ResourceLoaderAware.setResourceLoader()
5. ApplicationEventPublisherAware.setApplicationEventPublisher()
6. MessageSourceAware.setMessageSource()
7. ApplicationContextAware.setApplicationContext()
8. EnvironmentAware.setEnvironment()
9. EmbeddedValueResolverAware.setEmbeddedValueResolver()

阶段六:初始化前处理

6.1 postProcessBeforeInitialization

java
public interface BeanPostProcessor {
    /**
     * 在 Bean 初始化之前调用
     * 在以下初始化之前执行:
     * - Aware 接口回调已完成
     * - @PostConstruct 尚未执行
     * - InitializingBean.afterPropertiesSet() 尚未执行
     * - 自定义 init-method 尚未执行
     */
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
}

6.2 典型实现

java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 可以在这里进行一些预处理
        // 例如:注入额外属性、修改 Bean 状态等

        // 可以返回包装对象
        if (bean instanceof MyService) {
            return new MyServiceWrapper((MyService) bean);
        }

        return bean;
    }

    @Override
    public int getOrder() {
        return LOWEST_PRECEDENCE;
    }
}

6.3 Spring Boot 内置实现

java
// ConfigurationPropertiesBindingPostProcessor
// 负责将 @ConfigurationProperties 绑定到 Bean
public class ConfigurationPropertiesBindingPostProcessor
        implements BeanPostProcessor, PriorityOrdered, ApplicationContextAware {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 检查 Bean 是否有 @ConfigurationProperties 注解
        // 如果有,从环境变量中绑定属性
        bindConfigurationProperties(bean, beanName);
        return bean;
    }
}

阶段七:初始化回调

7.1 三种初始化方式(按执行顺序)

java
@Component
public class InitializationExample
        implements InitializingBean {

    // 1. @PostConstruct - JSR-250 标准(最先执行)
    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct called");
        // 此时属性已注入,可使用依赖
    }

    // 2. InitializingBean.afterPropertiesSet() - Spring 接口(其次执行)
    @Override
    public void afterPropertiesSet() {
        System.out.println("afterPropertiesSet called");
    }

    // 3. 自定义 init-method - 最后执行
    // XML: <bean init-method="customInit" />
    // Java Config: @Bean(initMethod = "customInit")
    public void customInit() {
        System.out.println("customInit called");
    }
}

7.2 @PostConstruct 详解

java
import javax.annotation.PostConstruct;

@Component
public class Service {

    @Autowired
    private Repository repository;

    /**
     * @PostConstruct 方法特点:
     * 1. 只能有一个
     * 2. 不能有参数
     * 3. 返回值必须是 void
     * 4. 不能抛出 checked exception(除了 Exception)
     * 5. 在依赖注入之后调用
     */
    @PostConstruct
    public void init() {
        // 初始化逻辑
        repository.connect();
    }
}

7.3 InitializingBean 接口

java
public interface InitializingBean {
    /**
     * 在所有属性设置完成后调用
     * 注意:可能抛出 Exception,需要在方法内处理
     */
    void afterPropertiesSet() throws Exception;
}

@Component
public class DatabaseService implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        // 验证必要属性是否已设置
        if (dataSource == null) {
            throw new IllegalStateException("DataSource must be set");
        }
        // 建立连接池等初始化操作
        initializeConnectionPool();
    }
}

7.4 自定义 init-method

java
// 方式 1: XML 配置
// <bean id="service" class="com.example.Service" init-method="init"/>

// 方式 2: Java Config
@Configuration
public class AppConfig {

    @Bean(initMethod = "init")
    public Service service() {
        return new Service();
    }
}

// 方式 3: @Bean 定义的 Bean 方法本身即初始化
@Configuration
public class AppConfig {

    @Bean
    public Service service() {
        Service s = new Service();
        // 这里的代码相当于 init-method
        s.setup();
        return s;
    }
}

阶段八:初始化后处理

8.1 postProcessAfterInitialization

java
public interface BeanPostProcessor {
    /**
     * 在 Bean 初始化之后调用
     * 在以下初始化之后执行:
     * - @PostConstruct 已执行
     * - InitializingBean.afterPropertiesSet() 已执行
     * - 自定义 init-method 已执行
     *
     * 返回值可以是被包装的对象(如 AOP 代理)
     */
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

8.2 AOP 代理的创建

这是 Spring AOP 的核心机制:

java
// AbstractAutoProxyCreator 是关键实现
public class AbstractAutoProxyCreator
        extends AbstractBeanPostProcessor
        implements SmartInstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 判断是否需要为 Bean 创建代理
        if (isInfrastructureClass(bean.getClass())) {
            return bean;
        }

        // 创建 AOP 代理
        Object proxy = createProxy(bean, beanName);
        return proxy;
    }
}

// 使用示例
@Service
@Transactional  // 触发 AOP 代理创建
public class OrderService {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createOrder(Order order) {
        // 事务由 AOP 代理管理
    }
}

8.3 多个 BeanPostProcessor 的执行

java
// 所有 BeanPostProcessor 按顺序执行
// 每个处理器都可以返回包装对象

@Component
public class FirstProcessor implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("FirstProcessor processing: " + beanName);
        return bean;
    }
    @Override public int getOrder() { return 0; }
}

@Component
public class SecondProcessor implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 此时 bean 可能已经被 FirstProcessor 包装
        System.out.println("SecondProcessor processing: " + beanName);
        return bean;
    }
    @Override public int getOrder() { return 1; }
}

8.4 Spring Boot 内置的 BeanPostProcessor

类名作用
ConfigurationPropertiesBindingPostProcessor绑定 @ConfigurationProperties
CommonsLoggingBeanPostProcessorCommons Logging 支持
ApplicationContextHealthIndicatorHealth 检查
InfrastructureAdvisorAutoProxyCreatorAOP 基础设施
AnnotationAwareAspectJAutoProxyCreatorAspectJ AOP 代理

阶段九:Bean 就绪使用

9.1 单例 Bean 缓存

java
// DefaultSingletonBeanRegistry 中的缓存结构
private final ConcurrentHashMap<String, Object> singletonObjects =
    new ConcurrentHashMap<>(256);

// Bean 初始化完成后放入此缓存
protected void addSingleton(String beanName, Object singletonObject) {
    this.singletonObjects.put(beanName, singletonObject);
}

9.2 SmartInitializingSingleton

java
public interface SmartInitializingSingleton {
    /**
     * 在所有单例 Bean 实例化完成后调用
     * 注意:不是容器刷新完成,只是单例 Bean 创建完成
     */
    void afterSingletonsInstantiated();
}

@Component
public class StartupInitializer implements SmartInitializingSingleton {

    @Override
    public void afterSingletonsInstantiated() {
        // 所有单例 Bean 已创建,可以安全使用它们
        // 常用于启动时的初始化任务
        System.out.println("All singletons instantiated!");
    }
}

9.3 容器启动完成的监听

java
// ApplicationListener<ApplicationReadyEvent>
@Component
public class ApplicationReadyHandler
        implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 容器完全启动,应用可以接受请求
        System.out.println("Application is ready!");
    }
}

阶段十:销毁回调

10.1 三种销毁方式(按执行顺序)

java
@Component
public class DestructionExample {

    // 1. @PreDestroy - JSR-250 标准(最先执行)
    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy called");
    }

    // 2. DisposableBean.destroy() - Spring 接口(其次执行)
    // 需要实现接口

    // 3. 自定义 destroy-method - 最后执行
    public void customDestroy() {
        System.out.println("customDestroy called");
    }
}

// 配置 destroy-method
@Bean(destroyMethod = "customDestroy")
public DestructionExample example() {
    return new DestructionExample();
}

10.2 @PreDestroy 注解

java
import javax.annotation.PreDestroy;

@Component
public class CacheService {

    @PreDestroy
    public void cleanup() {
        // 清理资源
        clearCache();
        closeConnections();
        System.out.println("Cache cleaned up");
    }
}

10.3 DisposableBean 接口

java
public interface DisposableBean {
    /**
     * 在 Bean 被销毁时调用
     * 可能抛出 Exception
     */
    void destroy() throws Exception;
}

@Component
public class DatabaseConnectionPool implements DisposableBean {

    @Override
    public void destroy() throws Exception {
        // 关闭数据库连接池
        connectionPool.close();
        System.out.println("Connection pool closed");
    }
}

10.4 销毁时机

java
// 销毁回调在以下情况触发:
// 1. 容器关闭:context.close()
// 2. 应用退出:Spring Boot 应用停止
// 3. 临时作用域 Bean 结束:request/session 结束

// 注意:prototype 作用域的 Bean 不会自动调用销毁方法
// 需要手动管理或使用 DestructionAwareBeanPostProcessor

BeanPostProcessor 深度解析

11.1 BeanPostProcessor 接口完整定义

java
public interface BeanPostProcessor {

    /**
     * Bean 实例化之后、初始化之前调用
     */
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    /**
     * Bean 初始化之后调用
     * 返回值将被用作最终的 Bean 引用(可用于 AOP 代理)
     */
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

11.2 完整生命周期中的位置

BeanPostProcessor 的两个钩子方法在生命周期中的位置:

[实例化] -> [属性填充] -> [Aware 回调]

           postProcessBeforeInitialization() ← 第一个钩子

          [@PostConstruct -> InitializingBean -> init-method]

           postProcessAfterInitialization() ← 第二个钩子

                       [Bean 可用]

11.3 实现 BeanPostProcessor

java
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor, Ordered {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("Before initialization: " + beanName);
        long startTime = System.currentTimeMillis();

        // 将开始时间存储在 bean 的属性中(假设可以访问)
        // 实际场景中可能需要 ThreadLocal 或其他机制

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("After initialization: " + beanName);

        // 可以进行额外的包装或修改
        if (bean instanceof Runnable) {
            return new LoggingRunnable((Runnable) bean);
        }

        return bean;
    }

    @Override
    public int getOrder() {
        return 0; // 数字越小优先级越高
    }
}

11.4 常见的 BeanPostProcessor 实现

1. MergedBeanDefinitionPostProcessor

java
public interface MergedBeanDefinitionPostProcessor {

    /**
     * 在 Bean 的属性合并后调用
     * 常用于读取泛型信息
     */
    default void postProcessMergedBeanDefinition(
            BeanDefinition mergedBeanDefinition,
            BeanMetadataElement attribute,
            String beanType) {
    }
}

// 示例:读取泛型参数的类型
@Component
public class GenericTypeDetector
        implements MergedBeanDefinitionPostProcessor {

    @Override
    public void postProcessMergedBeanDefinition(
            BeanDefinition beanDefinition,
            BeanMetadataElement attribute,
            String beanType) {

        // 可以获取泛型信息,用于类型安全的依赖注入
    }
}

2. DisposableBeanAdapter

java
// 适配 @PreDestroy 和 destroy-method 到 DisposableBean 接口
public class DisposableBeanAdapter
        implements DisposableBean, Serializable {

    public DisposableBeanAdapter(
            Object bean,
            String beanName,
            RootBeanDefinition beanDefinition,
            @Nullable Lifecycle lifecycle) {
        // 封装销毁逻辑
    }

    @Override
    public void destroy() throws Exception {
        // 按顺序调用:@PreDestroy -> destroy() -> destroy-method
        invokePreDestroyMethods();
        invokeDestroyMethods();
    }
}

InstantiationAwareBeanPostProcessor 详解

12.1 接口继承关系

BeanPostProcessor

InstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor

12.2 完整接口定义

java
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * 在 Bean 实例化之前调用
     * 返回非 null 值将作为 Bean 实例,跳过后续实例化过程
     */
    default Object postProcessBeforeInstantiation(
            Class<?> beanClass,
            String beanName) {
        return null;
    }

    /**
     * Bean 实例化之后调用
     * 返回 false 跳过属性填充
     */
    default boolean postProcessAfterInstantiation(
            Object bean,
            String beanName) {
        return true;
    }

    /**
     * 在属性填充之前调用
     * 可以修改要注入的属性值
     */
    default PropertyValues postProcessProperties(
            PropertyValues pvs,
            BeanInfo beanInfo,
            String beanName) {
        return pvs;
    }

    /**
     * 在依赖 Bean 准备注入之前调用
     * 可以修改或包装依赖
     */
    default Object postProcessInjectedElement(
            Object injectedValue,
            ParsedPropertyPropertyDependencyDescription pd) {
        return injectedValue;
    }

    /**
     * 在集合元素准备注入之前调用
     */
    default Object[] postProcessArgumentValues(
            ArgumentValues args,
            ParsedPropertyPropertyDependencies dependencies,
            String beanName) {
        return args.getArgumentValues();
    }
}

12.3 典型应用场景

java
@Component
public class MyInstantiationAwareBeanPostProcessor
        implements InstantiationAwareBeanPostProcessor {

    // 场景 1:自定义 Bean 实例
    @Override
    public Object postProcessBeforeInstantiation(
            Class<?> beanClass,
            String beanName) {

        if ("mySpecialBean".equals(beanName)) {
            // 返回自定义实例,跳过正常实例化
            return new CustomImplementation();
        }
        return null;
    }

    // 场景 2:跳过属性填充
    @Override
    public boolean postProcessAfterInstantiation(
            Object bean,
            String beanName) {

        // 某些特殊 Bean 不需要属性填充
        if (bean instanceof InfrastructureBean) {
            return false;
        }
        return true;
    }

    // 场景 3:修改属性值
    @Override
    public PropertyValues postProcessProperties(
            PropertyValues pvs,
            BeanInfo beanInfo,
            String beanName) {

        MutablePropertyValues mps = new MutablePropertyValues(pvs);
        // 添加或修改属性
        mps.addPropertyValue("newProperty", "value");
        return mps;
    }

    // 场景 4:修改注入的依赖
    @Override
    public Object postProcessInjectedElement(
            Object injectedValue,
            ParsedPropertyPropertyDependencyDescription pd) {

        // 包装注入的对象
        if (injectedValue instanceof Service) {
            return new MonitoringServiceWrapper((Service) injectedValue);
        }
        return injectedValue;
    }
}

12.4 SmartInstantiationAwareBeanPostProcessor

java
public interface SmartInstantiationAwareBeanPostProcessor
        extends InstantiationAwareBeanPostProcessor {

    /**
     * 判断是否需要为给定的 Bean 创建 EarlyReference
     * 用于解决循环依赖
     */
    default boolean requiresEarlyReference(String beanName) {
        return false;
    }
}

BeanFactoryPostProcessor 详解

13.1 接口对比

特性BeanFactoryPostProcessorBeanPostProcessor
作用对象BeanDefinitionBean 实例
执行时机所有 Bean 实例化之前每个 Bean 的实例化过程中
主要用途修改 Bean 定义修改/包装 Bean 实例
典型应用占位符解析、条件装配AOP 代理、属性增强

13.2 BeanDefinitionRegistryPostProcessor

java
public interface BeanDefinitionRegistryPostProcessor
        extends BeanFactoryPostProcessor {

    /**
     * 在 BeanDefinition 加载后、容器创建前调用
     * 可以注册新的 BeanDefinition
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
            throws BeansException;
}

// 实现示例:动态注册 Bean
@Component
public class DynamicBeanRegistryProcessor
        implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 检查是否已注册
        if (!registry.containsBeanDefinition("dynamicBean")) {
            RootBeanDefinition definition = new RootBeanDefinition(DynamicBean.class);
            registry.registerBeanDefinition("dynamicBean", definition);
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // BeanDefinition 处理完成后调用
    }
}

13.3 ConfigurationClassPostProcessor

Spring 处理@Configuration 类的核心处理器:

java
public class ConfigurationClassPostProcessor
        implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 1. 解析 @Configuration 类
        // 2. 处理 @ComponentScan
        // 3. 处理 @Import
        // 4. 处理 @Bean 方法
        // 5. 注册解析出的 BeanDefinition

        ConfigurationClassParser parser = new ConfigurationClassParser(...);
        parser.parse(configurationClasses);

        ConfigurationClassPostProcessor importer =
            new ConfigurationClassPostProcessor(...);
        importer.register(parser.getConfigurationClasses());
    }
}

Bean 作用域(Scope)

14.1 内置作用域

java
// 1. Singleton(默认)- 单例
@Bean  // 等同于 @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public Service service() {
    return new Service();
}

// 2. Prototype - 原型(每次获取都返回新实例)
@Bean(scope = "prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public PrototypeBean prototypeBean() {
    return new PrototypeBean();
}

// 3. Request - HTTP 请求级别(Web 应用)
@Scope("request")
public class RequestScopedBean { }

// 4. Session - HTTP 会话级别(Web 应用)
@Scope("session")
public class SessionScopedBean { }

// 5. Application - ServletContext 级别(Web 应用)
@Scope("websocket")
public class ApplicationScopedBean { }

14.2 @Scope 注解详解

java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {

    /** 作用域名称 */
    String value();

    /** 是否在作用域外创建代理 */
    boolean proxyMode() default ScopedProxyMode.NO;
}

// 代理模式说明:
// NO - 不创建代理(默认)
// INTERFACES - 基于接口创建 JDK 动态代理
// TARGET_CLASS - 基于 CGLIB 创建子类代理

14.3 作用域代理的必要性

java
// 问题:单例 Bean 依赖请求作用域 Bean
@RestController
public class UserController {  // 默认单例

    @Autowired
    private RequestBean requestBean;  // 请求作用域
    // 问题:单例在启动时注入,只得到一个 RequestBean 实例
}

// 解决方案:使用代理
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestBean { }

// 或者使用 ObjectProvider
@RestController
public class UserController {

    @Autowired
    private ObjectProvider<RequestBean> requestBeanProvider;

    @GetMapping
    public String handle() {
        // 每次获取都是新的请求作用域实例
        RequestBean bean = requestBeanProvider.getObject();
        return bean.getValue();
    }
}

14.4 自定义作用域

java
public class CustomScope extends AbstractScope {

    private final Map<String, Object> scopedObjects = new ConcurrentHashMap<>();

    @Override
    public Object get(String name, ObjectFactory<Object> objectFactory) {
        return scopedObjects.computeIfAbsent(name, k -> objectFactory.getObject());
    }

    @Override
    public Object remove(String name) {
        return scopedObjects.remove(name);
    }
}

// 注册自定义作用域
@Configuration
public class ScopeConfig {

    @Bean
    public CustomScope customScope() {
        return new CustomScope();
    }

    @Bean
    public ScopedBean scopedBean(CustomScope scope) {
        return new ScopedBean();
    }
}

// 使用
@Scope(value = "custom", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ScopedBean { }

14.5 Spring Boot DevTools 的 RestartScope

java
// 特殊的重启作用域,Bean 在应用重启时保持
@Scope("restart")
public class RestartScopedBean { }

// 或使用专用注解
@RestartScope
public class PersistentState { }

循环依赖处理

15.1 循环依赖类型

A ────► B ────► A  (双向循环依赖)
A ────► B ────► C ────► A  (多向循环依赖)

15.2 Spring 的三级缓存机制

java
// 一级缓存:完全初始化的单例 Bean
private final Map<String, Object> singletonObjects =
    new ConcurrentHashMap<>(256);

// 二级缓存:早期的 Bean 引用(未填充属性)
private final Map<String, Object> earlySingletonObjects =
    new HashMap<>();

// 三级缓存:Factory 用于创建早期引用
private final Map<String, Object> singletonFactories =
    new HashMap<>();

15.3 循环依赖解决流程

1. Bean A 开始创建
2. A 实例化完成,将 ObjectFactory<A> 放入三级缓存
3. A 填充属性时发现依赖 B
4. 开始创建 Bean B
5. B 实例化完成,将 ObjectFactory<B> 放入三级缓存
6. B 填充属性时发现依赖 A
7. 从三级缓存获取 A 的 ObjectFactory
8. 调用 ObjectFactory 得到 A 的早期引用
9. 将 A 的早期引用从三级移到二级缓存
10. B 完成初始化,放入一级缓存
11. A 继续初始化,使用 B 的最终引用
12. A 完成初始化,放入一级缓存

15.4 构造器循环依赖

java
// 这种情况无法解决!会抛出异常
@Service
public class ServiceA {
    private final ServiceB serviceB;

    @Autowired
    public ServiceA(ServiceB serviceB) {  // 构造器注入
        this.serviceB = serviceB;
    }
}

@Service
public class ServiceB {
    private final ServiceA serviceA;

    @Autowired
    public ServiceB(ServiceA serviceA) {  // 构造器注入
        this.serviceA = serviceA;
    }
}

// 错误:org.springframework.beans.factory.BeanCurrentlyInCreationException

15.5 解决方法

java
// 方法 1:使用 @DependsOn 明确依赖顺序
@Service
@DependsOn("serviceB")
public class ServiceA {
    private ServiceB serviceB;

    @Autowired
    public void setServiceB(ServiceB serviceB) {  // Setter 注入
        this.serviceB = serviceB;
    }
}

// 方法 2:使用 @Lazy 延迟加载
@Service
public class ServiceA {
    private final ServiceB serviceB;

    @Autowired
    public ServiceA(@Lazy ServiceB serviceB) {  // 懒加载代理
        this.serviceB = serviceB;
    }
}

// 方法 3:重构代码,提取公共部分
@Service
public class CommonService { }

@Service
public class ServiceA {
    private final CommonService commonService;

    @Autowired
    public ServiceA(CommonService commonService) {
        this.commonService = commonService;
    }
}

@Service
public class ServiceB {
    private final CommonService commonService;

    @Autowired
    public ServiceB(CommonService commonService) {
        this.commonService = commonService;
    }
}

15.6 配置循环依赖策略

java
// application.properties
spring.main.allow-circular-references=false  # Spring Boot 2.6+ 默认禁止

// 或在代码中配置
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setAllowCircularReferences(false);
        app.run(args);
    }
}

延迟加载机制

16.1 全局延迟加载配置

properties
# application.properties
spring.main.lazy-initialization=true
java
// 或在代码中配置
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setLazyInitialization(true);
        app.run(args);
    }
}

16.2 单个 Bean 延迟加载

java
// 方式 1: @Lazy 注解
@Service
@Lazy
public class LazyService { }

// 方式 2: @Bean 配置
@Bean(lazyInit = true)
public Service service() {
    return new Service();
}

// 方式 3: 构造器注入时使用 @Lazy
@Service
public class OrderService {
    private final HeavyService heavyService;

    @Autowired
    public OrderService(@Lazy HeavyService heavyService) {
        this.heavyService = heavyService;
    }
}

16.3 LazyInitializationBeanFactoryPostProcessor

java
public class LazyInitializationBeanFactoryPostProcessor
        implements BeanFactoryPostProcessor, Ordered {

    /**
     * 设置懒加载的规则:
     * 1. SmartInitializingSingleton 不参与懒加载
     * 2. 基础设施 Bean 不参与懒加载
     * 3. 被明确排除的 Bean 不参与懒加载
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
            if (!isExcluded(bd) && !bd.hasExplicitlySetLazyInit()) {
                bd.setLazyInit(true);
            }
        }
    }
}

16.4 延迟加载的影响

java
// 延迟加载的优点:
// 1. 加快应用启动速度
// 2. 减少启动时的内存占用
// 3. 失败的 Bean 不会阻塞启动

// 延迟加载的缺点:
// 1. 首次使用时可能有延迟
// 2. 循环依赖检测推迟
// 3. 某些初始化问题可能在运行时才暴露

// SmartInitializingSingleton 不受延迟加载影响
@Component
public class StartupTask implements SmartInitializingSingleton {
    @Override
    public void afterSingletonsInstantiated() {
        // 即使启用延迟加载,此方法仍会在启动时调用
    }
}

SmartInitializingSingleton 回调

17.1 接口定义

java
public interface SmartInitializingSingleton {
    /**
     * 在所有单例 Bean 实例化完成后调用
     * 注意:是在单例创建完成后,不是在容器刷新完成后
     */
    void afterSingletonsInstantiated();
}

17.2 执行时机

[所有单例 Bean 创建完成] → [SmartInitializingSingleton 回调]
→ [容器刷新完成] → [ApplicationReadyEvent]

17.3 使用场景

java
@Component
public class DataInitializer implements SmartInitializingSingleton {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Override
    public void afterSingletonsInstantiated() {
        // 所有 Bean 已创建,可以安全使用它们
        // 适合做一次性初始化工作

        // 1. 初始化基础数据
        initializeBaseData();

        // 2. 预热缓存
        warmUpCache();

        // 3. 建立外部连接
        establishExternalConnections();
    }

    private void initializeBaseData() {
        if (userRepository.count() == 0) {
            userRepository.save(new User("admin", "password"));
        }
    }
}

17.4 与其他初始化方式的对比

方式执行时机适用场景
@PostConstruct单个 Bean 初始化时Bean 自身初始化
SmartInitializingSingleton所有单例创建后跨 Bean 的初始化
ApplicationReadyEvent容器完全启动后应用级别的启动任务

最佳实践与注意事项

18.1 依赖注入的最佳实践

java
// ✅ 推荐:构造器注入
@Service
public class OrderService {
    private final PaymentService paymentService;

    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

// ⚠️ 不推荐:字段注入(难以测试,隐藏依赖)
@Service
public class BadOrderService {
    @Autowired
    private PaymentService paymentService;  // 依赖不明确
}

// ✅ 可选:Setter 注入(用于可选依赖)
@Service
public class OptionalService {
    private NotificationService notificationService;

    @Autowired(required = false)
    public void setNotificationService(NotificationService service) {
        this.notificationService = service;
    }
}

18.2 BeanPostProcessor 的使用建议

java
// ✅ 合理的 BeanPostProcessor
@Component
public class MetricBeanPostProcessor implements BeanPostProcessor, Ordered {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 仅为特定类型的 Bean 添加监控
        if (bean instanceof RestController) {
            return addMetricWrapper(bean, beanName);
        }
        return bean;
    }

    @Override
    public int getOrder() {
        return LOWEST_PRECEDENCE; // 让其他处理器先执行
    }
}

// ❌ 不推荐:过度使用 BeanPostProcessor
// 避免在 BPP 中做复杂业务逻辑,保持单一职责

18.3 生命周期回调的选择

java
// ✅ 推荐使用 @PostConstruct(标准、简洁)
@Component
public class Service {
    @PostConstruct
    public void init() {
        // 初始化逻辑
    }
}

// ⚠️ 谨慎使用 InitializingBean(耦合 Spring)
@Component
public class LegacyService implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        // 只有在需要抛出 checked exception 时使用
    }
}

18.4 销毁回调的注意事项

java
// ✅ 正确的销毁实现
@Component
public class ResourceHolder {

    @PreDestroy
    public void cleanup() {
        // 优雅关闭资源
        try {
            resource.close();
        } catch (IOException e) {
            logger.warn("Failed to close resource", e);
            // 不要抛出异常,避免影响其他 Bean 的销毁
        }
    }
}

// ❌ 错误的做法:在销毁时抛出异常
@PreDestroy
public void badCleanup() {
    if (condition) {
        throw new RuntimeException("Cleanup failed!");  // 可能导致容器无法关闭
    }
}

18.5 调试技巧

java
// 1. 打印 Bean 生命周期
@Configuration
public class LifecycleDebugConfig {

    @Bean
    public BeanPostProcessor debugBpp() {
        return new BeanPostProcessor() {
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) {
                System.out.println("BEFORE INIT: " + beanName);
                return bean;
            }

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) {
                System.out.println("AFTER INIT: " + beanName);
                return bean;
            }
        };
    }
}

// 2. 查看 Bean 的定义
@Autowired
private BeanFactory beanFactory;

public void debug() {
    String[] names = ((ListableBeanFactory) beanFactory).getBeanDefinitionNames();
    for (String name : names) {
        BeanDefinition bd = ((ConfigurableListableBeanFactory) beanFactory)
            .getBeanDefinition(name);
        System.out.println(name + ": " + bd.getBeanClassName());
    }
}

附录:完整生命周期代码示例

java
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class FullLifecycleBean
        implements InitializingBean, DisposableBean, ApplicationContextAware {

    private String beanName;
    private ApplicationContext context;

    // ========== Aware 回调 ==========

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        log("BeanNameAware.setBeanName(): " + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        this.context = ctx;
        log("ApplicationContextAware.setApplicationContext()");
    }

    // ========== 初始化回调 ==========

    @PostConstruct
    public void postConstruct() {
        log("@PostConstruct - 第一个初始化回调");
    }

    @Override
    public void afterPropertiesSet() {
        log("InitializingBean.afterPropertiesSet() - 第二个初始化回调");
    }

    public void customInit() {
        log("customInit() - 第三个初始化回调(通过 initMethod 指定)");
    }

    // ========== 业务方法 ==========

    public void doWork() {
        log("Executing business logic...");
    }

    // ========== 销毁回调 ==========

    @PreDestroy
    public void preDestroy() {
        log("@PreDestroy - 第一个销毁回调");
    }

    @Override
    public void destroy() {
        log("DisposableBean.destroy() - 第二个销毁回调");
    }

    public void customDestroy() {
        log("customDestroy() - 第三个销毁回调(通过 destroyMethod 指定)");
    }

    private void log(String message) {
        System.out.println("[FullLifecycleBean] " + message);
    }
}

// 配置
@Configuration
public class AppConfig {

    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public FullLifecycleBean fullLifecycleBean() {
        return new FullLifecycleBean();
    }
}

总结

Spring Bean 的生命周期是一个精心设计的系统,提供了多个扩展点供开发者定制 Bean 的创建和行为。关键要点:

  1. BeanFactoryPostProcessor 在 Bean 实例化前修改 BeanDefinition
  2. BeanPostProcessor 在 Bean 实例化前后进行加工(AOP 的基础)
  3. Aware 接口 让 Bean 感知容器环境
  4. 初始化回调 有三种方式:@PostConstruct、InitializingBean、init-method
  5. 销毁回调 有三种方式:@PreDestroy、DisposableBean、destroy-method
  6. 循环依赖 通过三级缓存解决 setter 注入的情况
  7. 作用域 控制 Bean 的实例数量和管理范围
  8. 延迟加载 优化启动时间和内存占用

深入理解这些机制,能够帮助你更好地使用 Spring 框架,编写更高效、更灵活的代码。

更新于:

note