Spring Bean 生命周期管理完整指南
目录
- 概述
- Bean 生命周期的完整流程
- 阶段一:BeanDefinition 加载与处理
- 阶段二:BeanFactoryPostProcessor 处理
- 阶段三:Bean 实例化
- 阶段四:属性填充
- 阶段五:Aware 接口回调
- 阶段六:初始化前处理
- 阶段七:初始化回调
- 阶段八:初始化后处理
- 阶段九:Bean 就绪使用
- 阶段十:销毁回调
- BeanPostProcessor 深度解析
- InstantiationAwareBeanPostProcessor 详解
- BeanFactoryPostProcessor 详解
- Bean 作用域(Scope)
- 循环依赖处理
- 延迟加载机制
- SmartInitializingSingleton 回调
- 最佳实践与注意事项
概述
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 |
CommonsLoggingBeanPostProcessor | Commons Logging 支持 |
ApplicationContextHealthIndicator | Health 检查 |
InfrastructureAdvisorAutoProxyCreator | AOP 基础设施 |
AnnotationAwareAspectJAutoProxyCreator | AspectJ 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 不会自动调用销毁方法
// 需要手动管理或使用 DestructionAwareBeanPostProcessorBeanPostProcessor 深度解析
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
↑
SmartInstantiationAwareBeanPostProcessor12.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 接口对比
| 特性 | BeanFactoryPostProcessor | BeanPostProcessor |
|---|---|---|
| 作用对象 | BeanDefinition | Bean 实例 |
| 执行时机 | 所有 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.BeanCurrentlyInCreationException15.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=truejava
// 或在代码中配置
@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 的创建和行为。关键要点:
- BeanFactoryPostProcessor 在 Bean 实例化前修改 BeanDefinition
- BeanPostProcessor 在 Bean 实例化前后进行加工(AOP 的基础)
- Aware 接口 让 Bean 感知容器环境
- 初始化回调 有三种方式:@PostConstruct、InitializingBean、init-method
- 销毁回调 有三种方式:@PreDestroy、DisposableBean、destroy-method
- 循环依赖 通过三级缓存解决 setter 注入的情况
- 作用域 控制 Bean 的实例数量和管理范围
- 延迟加载 优化启动时间和内存占用
深入理解这些机制,能够帮助你更好地使用 Spring 框架,编写更高效、更灵活的代码。
