一、前言:为什么需要深入理解Bean生命周期?
在Spring框架中,[Bean生命周期]管理是IoC容器的核心功能。深入理解Bean生命周期对于以下场景至关重要:
- 性能优化:合理使用生命周期回调,避免资源泄漏和性能瓶颈
- 扩展开发:自定义Bean初始化、销毁逻辑,实现框架扩展
- 问题排查:快速定位Bean创建、初始化、销毁过程中的问题
- 高级特性:理解Bean作用域、延迟加载、AOP代理等特性的实现原理
让我们从一个简单的例子开始,看看如果不懂Bean生命周期可能遇到的问题:
typescript
@Component
public class DatabaseConnection {
private Connection connection;
public DatabaseConnection() {
// 错误:在构造函数中初始化连接
this.connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test");
}
public void query(String sql) {
// 使用connection执行查询
}
// 问题:没有关闭连接的方法,会导致连接泄漏!
}
AI写代码java
运行
123456789101112131415
二、Bean生命周期全景图
在深入细节之前,先通过一张全景图了解Bean的完整生命周期:
sql
┌─────────────────────────────────────────────────────────────────────────┐
│ Spring Bean 完整生命周期 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 实例化 │───▶│ 属性赋值 │───▶│ Aware接口 │ │
│ │ Instantiate │ │ Populate │ │ 回调 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ┌──────▼──────────────────▼───────────────────▼──────┐ │
│ │ BeanPostProcessor │ │
│ │ (前置处理 PostProcessBefore) │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼─────────────────────────────────────────────┐ │
│ │ 初始化方法 (InitializingBean) │ │
│ │ 1. @PostConstruct 2. afterPropertiesSet() │ │
│ │ 3. init-method │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼─────────────────────────────────────────────┐ │
│ │ BeanPostProcessor │ │
│ │ (后置处理 PostProcessAfter) │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼──────────────┐ 使用期 ┌───────────────┐ │
│ │ Bean就绪 │───────────▶│ Bean使用 │ │
│ │ (Ready for Use) │ │ (In Use) │ │
│ └─────────────────────┘ └───────────────┘ │
│ │ │ │
│ ┌──────▼─────────────────────────────────────▼──────┐ │
│ │ 销毁阶段 │ │
│ │ 1. @PreDestroy 2. DisposableBean │ │
│ │ 3. destroy-method │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
AI写代码
12345678910111213141516171819202122232425262728293031323334353637
三、Bean生命周期第一阶段:实例化与属性赋值
3.1 Bean实例化(Instantiation)
实例化是Bean生命周期的第一步,Spring容器通过以下方式创建Bean实例:
3.1.1 构造器实例化(最常用)
kotlin
@Component
public class UserService {
private final UserRepository userRepository;
// 通过构造器注入依赖
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
System.out.println("1. UserService 实例化 - 构造器调用");
}
}
AI写代码java
运行
1234567891011
3.1.2 静态工厂方法实例化
kotlin
@Configuration
public class BeanConfig {
@Bean
public static DataSource dataSource() {
// 静态工厂方法创建Bean
System.out.println("通过静态工厂方法创建DataSource");
return DataSourceBuilder.create().build();
}
}
AI写代码java
运行
12345678910
3.1.3 实例工厂方法实例化
typescript
@Component
public class ServiceFactory {
@Bean
public UserService userService() {
// 实例工厂方法创建Bean
return new UserService();
}
}
AI写代码java
运行
123456789
3.1.4 FactoryBean接口实现
typescript
@Component
public class MyFactoryBean implements FactoryBean<UserService> {
@Override
public UserService getObject() throws Exception {
// 复杂的创建逻辑
return new UserService(createSpecialRepository());
}
@Override
public Class<?> getObjectType() {
return UserService.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
AI写代码java
运行
12345678910111213141516171819
3.2 属性赋值(Populate Properties)
实例化完成后,Spring容器开始为Bean注入依赖:
kotlin
@Component
public class OrderService {
// 1. 字段注入
@Autowired
private OrderRepository orderRepository;
// 2. 构造器注入(推荐)
private final UserService userService;
@Autowired
public OrderService(UserService userService) {
this.userService = userService;
}
// 3. Setter方法注入
private PaymentService paymentService;
@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
System.out.println("2. OrderService 属性注入 - paymentService");
}
// 4. @Value注入
@Value("${app.order.max-items:10}")
private int maxItems;
// 5. @Resource注入(JSR-250)
@Resource(name = "emailService")
private NotificationService notificationService;
}
AI写代码java
运行
1234567891011121314151617181920212223242526272829303132
属性赋值阶段的重要处理:
- 依赖解析:解析@Autowired、@Value等注解
- 循环依赖处理:通过三级缓存解决循环依赖问题
- 属性值转换:将配置值转换为目标类型
- 表达式求值:处理SpEL表达式
四、Bean生命周期第二阶段:Aware接口回调
Aware接口是Spring提供的回调接口,让Bean能够感知容器信息:
4.1 常用的Aware接口
typescript
@Component
public class AwareBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
EnvironmentAware,
ResourceLoaderAware,
ApplicationEventPublisherAware,
MessageSourceAware {
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
private Environment environment;
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("3.1 Aware回调 - BeanNameAware: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("3.2 Aware回调 - BeanFactoryAware");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("3.3 Aware回调 - ApplicationContextAware");
// 可以通过ApplicationContext获取其他Bean
UserService userService = applicationContext.getBean(UserService.class);
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
System.out.println("3.4 Aware回调 - EnvironmentAware");
// 获取配置文件中的值
String appName = environment.getProperty("app.name");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("3.5 Aware回调 - ResourceLoaderAware");
// 加载资源文件
Resource resource = resourceLoader.getResource("classpath:config.properties");
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("3.6 Aware回调 - ApplicationEventPublisherAware");
// 发布应用事件
applicationEventPublisher.publishEvent(new CustomEvent(this, "AwareBean创建完成"));
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("3.7 Aware回调 - MessageSourceAware");
// 国际化消息
String message = messageSource.getMessage("welcome.message", null, Locale.getDefault());
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
4.2 Aware接口执行顺序
Aware接口回调有严格的执行顺序:
markdown
1. BeanNameAware
2. BeanClassLoaderAware
3. BeanFactoryAware
4. EnvironmentAware
5. EmbeddedValueResolverAware
6. ResourceLoaderAware
7. ApplicationEventPublisherAware
8. MessageSourceAware
9. ApplicationContextAware
AI写代码
123456789
重要提示 :ApplicationContextAware总是在最后执行,因为此时Bean已经完全初始化,可以安全地使用ApplicationContext。
五、Bean生命周期第三阶段:BeanPostProcessor处理
BeanPostProcessor是Spring最重要的扩展点之一,允许在Bean初始化前后进行自定义处理:
5.1 BeanPostProcessor接口详解
typescript
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("4.1 BeanPostProcessor前置处理 - bean: " + beanName + ", type: " + bean.getClass());
// 示例:为特定类型的Bean添加代理
if (bean instanceof UserService) {
System.out.println(" >>> 为UserService创建代理");
return createProxy(bean);
}
// 示例:处理带有特定注解的Bean
if (bean.getClass().isAnnotationPresent(Metric.class)) {
System.out.println(" >>> 为Metric注解的Bean添加监控");
return wrapWithMetrics(bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("5.1 BeanPostProcessor后置处理 - bean: " + beanName);
// 示例:Bean初始化后的处理
if (bean instanceof InitializingBean) {
System.out.println(" >>> " + beanName + " 实现了InitializingBean接口");
}
return bean;
}
@Override
public int getOrder() {
// 控制执行顺序,值越小优先级越高
return Ordered.HIGHEST_PRECEDENCE;
}
private Object createProxy(Object target) {
// 创建动态代理的逻辑
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("代理拦截方法: " + method.getName());
return method.invoke(target, args);
}
);
}
private Object wrapWithMetrics(Object target) {
// 包装监控逻辑
return target; // 简化示例
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
5.2 重要的内置BeanPostProcessor
Spring内置了许多重要的BeanPostProcessor:
| BeanPostProcessor类 | 作用 | 执行时机 |
|---|---|---|
AutowiredAnnotationBeanPostProcessor |
处理@Autowired、@Value、@Inject注解 | Before |
CommonAnnotationBeanPostProcessor |
处理@PostConstruct、@PreDestroy、@Resource等 | Before/After |
ApplicationContextAwareProcessor |
处理Aware接口回调 | Before |
InitDestroyAnnotationBeanPostProcessor |
处理@PostConstruct和@PreDestroy | Before/After |
AnnotationAwareAspectJAutoProxyCreator |
创建AOP代理 | After |
5.3 自定义BeanPostProcessor的最佳实践
java
@Component
public class ValidationBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
private final Validator validator;
public ValidationBeanPostProcessor() {
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 为带有@Validated注解的Bean创建代理
if (bean.getClass().isAnnotationPresent(org.springframework.validation.annotation.Validated.class)) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
new ValidationInvocationHandler(bean, validator)
);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public int getOrder() {
// 设置优先级,确保在AOP代理之前执行
return Ordered.LOWEST_PRECEDENCE - 1;
}
private static class ValidationInvocationHandler implements InvocationHandler {
private final Object target;
private final Validator validator;
public ValidationInvocationHandler(Object target, Validator validator) {
this.target = target;
this.validator = validator;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 参数校验
if (args != null) {
for (Object arg : args) {
Set<ConstraintViolation<Object>> violations = validator.validate(arg);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
}
// 执行原方法
Object result = method.invoke(target, args);
// 返回值校验
if (method.getReturnType() != void.class && result != null) {
Set<ConstraintViolation<Object>> violations = validator.validate(result);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
return result;
}
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
六、Bean生命周期第四阶段:初始化方法
初始化是Bean生命周期中最关键的阶段之一,Spring提供了三种初始化方式:
6.1 三种初始化方式的执行顺序
csharp
@Component
@Lazy
public class LifecycleBean implements InitializingBean {
private boolean initialized = false;
public LifecycleBean() {
System.out.println("1. 构造器执行");
}
@PostConstruct
public void postConstruct() {
System.out.println("4.2 @PostConstruct方法执行");
this.initialized = true;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("4.3 InitializingBean.afterPropertiesSet()执行");
// 执行复杂的初始化逻辑
initializeResources();
}
@Bean(initMethod = "customInit")
public void customInit() {
System.out.println("4.4 init-method指定的自定义初始化方法执行");
// 最后的初始化逻辑
verifyInitialization();
}
private void initializeResources() {
System.out.println(" 初始化数据库连接池...");
System.out.println(" 加载缓存数据...");
System.out.println(" 启动后台线程...");
}
private void verifyInitialization() {
if (!initialized) {
throw new IllegalStateException("Bean初始化失败");
}
System.out.println(" Bean初始化验证通过");
}
public void doSomething() {
System.out.println("6. Bean使用中...");
}
}
AI写代码java
运行
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
重要:三种初始化方法的执行顺序是固定的:
@PostConstruct注解的方法InitializingBean.afterPropertiesSet()方法- XML或注解中指定的
init-method
6.2 初始化阶段的最佳实践
csharp
@Component
public class DataSourceManager implements InitializingBean, DisposableBean {
private DataSource dataSource;
private ConnectionPool connectionPool;
private ScheduledExecutorService scheduler;
@Value("${datasource.url}")
private String url;
@Value("${datasource.username}")
private String username;
@Value("${datasource.password}")
private String password;
@Value("${datasource.pool.size:10}")
private int poolSize;
@PostConstruct
public void validateConfiguration() {
// 1. 配置验证(最先执行)
Assert.hasText(url, "数据库URL不能为空");
Assert.hasText(username, "数据库用户名不能为空");
System.out.println("配置验证通过");
}
@Override
public void afterPropertiesSet() throws Exception {
// 2. 资源初始化(主要初始化逻辑)
System.out.println("开始初始化数据源...");
// 创建数据源
this.dataSource = createDataSource();
// 初始化连接池
this.connectionPool = createConnectionPool();
// 启动健康检查
startHealthCheck();
System.out.println("数据源初始化完成");
}
@Bean(initMethod = "startMonitoring")
public void startMonitoring() {
// 3. 启动监控(最后执行)
System.out.println("启动数据源监控...");
this.scheduler = Executors.newScheduledThreadPool(1);
this.scheduler.scheduleAtFixedRate(this::monitorConnectionPool,
0, 30, TimeUnit.SECONDS);
}
private DataSource createDataSource() {
// 创建HikariCP数据源
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
config.setMaximumPoolSize(poolSize);
return new HikariDataSource(config);
}
private ConnectionPool createConnectionPool() {
// 自定义连接池逻辑
return new ConnectionPool(poolSize, dataSource);
}
private void startHealthCheck() {
// 启动健康检查线程
new Thread(() -> {
while (true) {
try {
checkDataSourceHealth();
Thread.sleep(60000); // 每分钟检查一次
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
}
private void monitorConnectionPool() {
// 监控连接池状态
int activeConnections = connectionPool.getActiveCount();
int idleConnections = connectionPool.getIdleCount();
System.out.printf("连接池状态 - 活跃: %d, 空闲: %d%n",
activeConnections, idleConnections);
}
private void checkDataSourceHealth() {
try (Connection conn = dataSource.getConnection()) {
if (conn.isValid(5)) {
System.out.println("数据源健康检查通过");
}
} catch (SQLException e) {
System.err.println("数据源健康检查失败: " + e.getMessage());
}
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
七、Bean生命周期第五阶段:BeanPostProcessor后置处理
在初始化方法执行完成后,BeanPostProcessor的后置处理方法被调用:
7.1 后置处理的典型应用
typescript
@Component
public class AopProxyPostProcessor implements BeanPostProcessor {
private final DefaultAopProxyFactory proxyFactory = new DefaultAopProxyFactory();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 检查是否需要创建AOP代理
if (needsProxy(bean, beanName)) {
System.out.println("5.2 为 " + beanName + " 创建AOP代理");
// 获取目标类的所有Advisor
List<Advisor> advisors = findEligibleAdvisors(bean.getClass());
if (!advisors.isEmpty()) {
// 创建代理
return createProxy(bean, advisors);
}
}
return bean;
}
private boolean needsProxy(Object bean, String beanName) {
// 排除基础设施Bean
if (beanName.startsWith("org.springframework")) {
return false;
}
// 检查是否有需要代理的切面
Class<?> beanClass = bean.getClass();
return hasAspectAnnotations(beanClass) || isEligibleForAutoProxy(beanClass);
}
private List<Advisor> findEligibleAdvisors(Class<?> beanClass) {
// 查找适用的Advisor
// 实际实现中会从ApplicationContext中获取所有Advisor并进行匹配
return Collections.emptyList(); // 简化示例
}
private Object createProxy(Object target, List<Advisor> advisors) {
// 使用Spring AOP API创建代理
AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTarget(target);
advisedSupport.setAdvisors(advisors.toArray(new Advisor[0]));
return proxyFactory.createAopProxy(advisedSupport).getProxy();
}
private boolean hasAspectAnnotations(Class<?> beanClass) {
// 检查类或方法上是否有AOP相关注解
return beanClass.isAnnotationPresent(Aspect.class) ||
Arrays.stream(beanClass.getMethods())
.anyMatch(m -> m.isAnnotationPresent(Before.class) ||
m.isAnnotationPresent(After.class) ||
m.isAnnotationPresent(Around.class));
}
private boolean isEligibleForAutoProxy(Class<?> beanClass) {
// 检查是否应该自动代理
// 例如:所有@Service、@Controller注解的类
return beanClass.isAnnotationPresent(Service.class) ||
beanClass.isAnnotationPresent(Controller.class) ||
beanClass.isAnnotationPresent(RestController.class);
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
7.2 代理创建的实际过程
在Spring AOP中,代理创建主要在AbstractAutoProxyCreator中完成:
scss
// Spring AOP创建代理的核心逻辑(简化版)
public abstract class AbstractAutoProxyCreator implements BeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
// 生成缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 检查是否已经创建过代理
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 如果需要代理,则创建代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
return bean;
}
// 获取适用的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 创建代理
return createProxy(bean.getClass(), beanName, specificInterceptors, bean);
}
}
}
return bean;
}
protected Object createProxy(Class<?> beanClass, String beanName,
Object[] specificInterceptors, Object targetSource) {
// 1. 创建ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 2. 配置代理目标
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 3. 添加Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 4. 设置目标对象
proxyFactory.setTargetSource(createTargetSource(targetSource));
// 5. 自定义代理工厂
customizeProxyFactory(proxyFactory);
// 6. 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
八、Bean生命周期第六阶段:使用期
Bean初始化完成后,就进入了使用期:
8.1 Bean作用域对生命周期的影响
kotlin
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeBean {
private static int instanceCount = 0;
private final int id;
public PrototypeBean() {
this.id = ++instanceCount;
System.out.println("PrototypeBean实例" + id + "创建");
}
@PostConstruct
public void init() {
System.out.println("PrototypeBean实例" + id + "初始化");
}
@PreDestroy
public void destroy() {
System.out.println("PrototypeBean实例" + id + "销毁");
// 注意:原型Bean的@PreDestroy不会被Spring调用!
}
}
@RestController
public class TestController {
@Autowired
private ApplicationContext context;
@GetMapping("/test")
public String test() {
// 每次请求都会创建新的PrototypeBean实例
PrototypeBean bean1 = context.getBean(PrototypeBean.class);
PrototypeBean bean2 = context.getBean(PrototypeBean.class);
System.out.println("Bean1 ID: " + bean1.getId());
System.out.println("Bean2 ID: " + bean2.getId());
System.out.println("是否相同实例: " + (bean1 == bean2));
return "测试完成";
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243
8.2 Bean在应用中的使用模式
java
@Component
public class BeanUsagePatterns {
// 1. 单例Bean注入
@Autowired
private UserService userService; // 单例,整个应用共享
// 2. 原型Bean通过Provider延迟获取
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
// 3. 延迟初始化Bean
@Lazy
@Autowired
private HeavyResource heavyResource; // 第一次使用时才初始化
// 4. 按需查找Bean
@Autowired
private ApplicationContext applicationContext;
public void demonstratePatterns() {
// 模式1:直接使用单例Bean
User user = userService.getUser(1L);
// 模式2:每次获取新的原型Bean
PrototypeBean prototype1 = prototypeBeanProvider.getObject();
PrototypeBean prototype2 = prototypeBeanProvider.getObject();
// 模式3:延迟初始化的Bean第一次使用
heavyResource.process(); // 此时才会初始化HeavyResource
// 模式4:动态查找Bean
if (needCache()) {
CacheService cacheService = applicationContext.getBean(CacheService.class);
cacheService.put("key", "value");
}
}
// 5. 使用@Lookup方法获取原型Bean
@Lookup
public PrototypeBean createPrototypeBean() {
// 方法体不会被执行,Spring会覆盖此方法
return null;
}
private boolean needCache() {
return true;
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
九、Bean生命周期第七阶段:销毁
Bean销毁阶段是生命周期的最后阶段,确保资源正确释放:
9.1 三种销毁方式的执行顺序
csharp
@Component
public class ResourceHolder implements DisposableBean {
private List<Connection> connections = new ArrayList<>();
private ScheduledExecutorService executorService;
private CacheManager cacheManager;
@PostConstruct
public void init() {
System.out.println("ResourceHolder初始化");
this.executorService = Executors.newScheduledThreadPool(2);
this.cacheManager = new ConcurrentMapCacheManager();
// 初始化资源
for (int i = 0; i < 3; i++) {
connections.add(createConnection());
}
}
@PreDestroy
public void preDestroy() {
System.out.println("7.1 @PreDestroy方法执行");
// 第一优先级:快速清理
cacheManager.clearCaches();
System.out.println(" >>> 缓存已清理");
}
@Override
public void destroy() throws Exception {
System.out.println("7.2 DisposableBean.destroy()方法执行");
// 第二优先级:资源释放
shutdownExecutorService();
System.out.println(" >>> 线程池已关闭");
}
@Bean(destroyMethod = "customDestroy")
public void customDestroy() {
System.out.println("7.3 destroy-method指定的自定义销毁方法执行");
// 第三优先级:最终清理
closeAllConnections();
System.out.println(" >>> 所有连接已关闭");
}
private Connection createConnection() {
// 模拟创建连接
return new Connection();
}
private void shutdownExecutorService() {
if (executorService != null) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
private void closeAllConnections() {
for (Connection conn : connections) {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
System.err.println("关闭连接失败: " + e.getMessage());
}
}
connections.clear();
}
static class Connection {
boolean isClosed = false;
void close() throws SQLException {
isClosed = true;
}
boolean isClosed() {
return isClosed;
}
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
9.2 销毁阶段的最佳实践
csharp
@Component
public class GracefulShutdownHandler implements DisposableBean, SmartLifecycle {
private volatile boolean running = false;
private final List<ShutdownHook> shutdownHooks = new CopyOnWriteArrayList<>();
private final ScheduledExecutorService monitorExecutor =
Executors.newSingleThreadScheduledExecutor();
@Override
public void start() {
System.out.println("GracefulShutdownHandler启动");
this.running = true;
// 注册JVM关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
// 启动健康监控
monitorExecutor.scheduleAtFixedRate(this::monitorSystem,
0, 30, TimeUnit.SECONDS);
}
@Override
public void stop() {
shutdown();
}
@Override
public boolean isRunning() {
return running;
}
@Override
public void destroy() throws Exception {
System.out.println("执行GracefulShutdownHandler销毁逻辑");
monitorExecutor.shutdownNow();
}
@PreDestroy
public void preDestroy() {
System.out.println("开始优雅关闭...");
// 1. 停止接收新请求
stopAcceptingNewRequests();
// 2. 等待处理中的请求完成(最长30秒)
waitForInflightRequests(30);
// 3. 执行注册的关闭钩子
executeShutdownHooks();
// 4. 释放资源
releaseResources();
System.out.println("优雅关闭完成");
}
public void registerShutdownHook(ShutdownHook hook) {
shutdownHooks.add(hook);
}
private void shutdown() {
if (running) {
running = false;
preDestroy();
}
}
private void stopAcceptingNewRequests() {
System.out.println("停止接收新请求...");
// 实际实现中可能设置负载均衡器状态、关闭端口监听等
}
private void waitForInflightRequests(int timeoutSeconds) {
System.out.println("等待处理中的请求完成,最多等待" + timeoutSeconds + "秒...");
long deadline = System.currentTimeMillis() + timeoutSeconds * 1000L;
int remainingRequests = getInflightRequestCount();
while (remainingRequests > 0 && System.currentTimeMillis() < deadline) {
try {
Thread.sleep(1000);
remainingRequests = getInflightRequestCount();
System.out.println("剩余请求数: " + remainingRequests);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
if (remainingRequests > 0) {
System.out.println("超时,强制关闭,剩余请求数: " + remainingRequests);
} else {
System.out.println("所有请求处理完成");
}
}
private void executeShutdownHooks() {
System.out.println("执行关闭钩子...");
// 按优先级执行关闭钩子
shutdownHooks.stream()
.sorted(Comparator.comparingInt(ShutdownHook::getPriority).reversed())
.forEach(hook -> {
try {
System.out.println("执行关闭钩子: " + hook.getName());
hook.execute();
} catch (Exception e) {
System.err.println("关闭钩子执行失败: " + hook.getName() + ", 错误: " + e.getMessage());
}
});
}
private void releaseResources() {
System.out.println("释放资源...");
// 关闭数据库连接池、线程池等
}
private int getInflightRequestCount() {
// 获取当前正在处理的请求数
return 0; // 简化实现
}
private void monitorSystem() {
// 监控系统状态
}
public interface ShutdownHook {
String getName();
int getPriority(); // 优先级,值越大越先执行
void execute();
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
十、特殊Bean的生命周期处理
10.1 FactoryBean的生命周期
csharp
@Component
public class ComplexServiceFactory implements FactoryBean<ComplexService>,
InitializingBean,
DisposableBean {
private ComplexService complexService;
private boolean initialized = false;
@Override
public ComplexService getObject() throws Exception {
if (!initialized) {
throw new IllegalStateException("FactoryBean未初始化");
}
System.out.println("FactoryBean.getObject()被调用");
return complexService;
}
@Override
public Class<?> getObjectType() {
return ComplexService.class;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("FactoryBean初始化开始");
// 复杂的初始化逻辑
this.complexService = new ComplexService();
this.complexService.setConfig(loadConfig());
this.complexService.setCache(initializeCache());
this.complexService.setExecutor(createThreadPool());
this.initialized = true;
System.out.println("FactoryBean初始化完成");
}
@Override
public void destroy() throws Exception {
System.out.println("FactoryBean销毁开始");
if (complexService != null) {
complexService.shutdown();
}
System.out.println("FactoryBean销毁完成");
}
private Config loadConfig() {
// 加载配置
return new Config();
}
private Cache initializeCache() {
// 初始化缓存
return new LocalCache();
}
private ExecutorService createThreadPool() {
// 创建线程池
return Executors.newFixedThreadPool(4);
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
10.2 BeanDefinitionRegistryPostProcessor的生命周期
java
@Component
public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry执行");
// 动态注册BeanDefinition
registerDynamicBeans(registry);
// 修改已有的BeanDefinition
modifyExistingBeanDefinitions(registry);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BeanDefinitionRegistryPostProcessor.postProcessBeanFactory执行");
// 对BeanFactory进行后处理
customizeBeanFactory(beanFactory);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
private void registerDynamicBeans(BeanDefinitionRegistry registry) {
System.out.println("动态注册Bean...");
// 示例:根据配置动态注册数据源
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(DataSource.class)
.setFactoryMethod("createDataSource")
.addPropertyValue("url", "jdbc:mysql://localhost:3306/dynamic")
.addPropertyValue("username", "root")
.addPropertyValue("password", "password")
.setScope(BeanDefinition.SCOPE_SINGLETON)
.setLazyInit(true);
registry.registerBeanDefinition("dynamicDataSource", builder.getBeanDefinition());
// 注册条件化的Bean
if (shouldRegisterFeatureBean()) {
BeanDefinition featureBean = BeanDefinitionBuilder
.genericBeanDefinition(FeatureService.class)
.getBeanDefinition();
registry.registerBeanDefinition("featureService", featureBean);
}
}
private void modifyExistingBeanDefinitions(BeanDefinitionRegistry registry) {
// 修改已有的BeanDefinition
String[] beanNames = registry.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
// 为所有Service添加自定义属性
if (beanDefinition.getBeanClassName() != null &&
beanDefinition.getBeanClassName().contains("Service")) {
beanDefinition.setAttribute("monitored", "true");
beanDefinition.setInitMethodName("init");
beanDefinition.setDestroyMethodName("cleanup");
}
}
}
private void customizeBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 添加自定义作用域
beanFactory.registerScope("tenant", new TenantScope());
// 添加自定义TypeConverter
beanFactory.setTypeConverter(new CustomTypeConverter());
// 添加后处理器
beanFactory.addBeanPostProcessor(new CustomBeanPostProcessor());
}
private boolean shouldRegisterFeatureBean() {
// 根据条件判断是否注册Feature Bean
return true;
}
}
AI写代码java
运行
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
十一、Bean生命周期中的常见问题与解决方案
11.1 循环依赖问题
kotlin
@Component
public class CircularDependencyDemo {
// 构造器循环依赖(Spring无法解决)
// @Component
// class ServiceA {
// public ServiceA(ServiceB serviceB) { ... }
// }
//
// @Component
// class ServiceB {
// public ServiceB(ServiceA serviceA) { ... }
// }
// Setter/字段注入循环依赖(Spring可以解决)
@Component
class ServiceC {
@Autowired
private ServiceD serviceD;
@PostConstruct
public void init() {
System.out.println("ServiceC初始化");
}
}
@Component
class ServiceD {
@Autowired
private ServiceC serviceC;
@PostConstruct
public void init() {
System.out.println("ServiceD初始化");
}
}
}
// Spring解决循环依赖的三级缓存机制:
// 第一级缓存:singletonObjects - 完全初始化好的单例Bean
// 第二级缓存:earlySingletonObjects - 早期曝光对象(半成品)
// 第三级缓存:singletonFactories - 单例工厂(用于创建早期曝光对象)
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142
11.2 初始化顺序问题
typescript
@Configuration
public class InitializationOrderConfig {
// 使用@DependsOn控制初始化顺序
@Bean
@DependsOn({"databaseInitializer", "cacheManager"})
public UserService userService() {
return new UserService();
}
@Bean(initMethod = "init")
public DatabaseInitializer databaseInitializer() {
return new DatabaseInitializer();
}
@Bean
public CacheManager cacheManager() {
return new CacheManager();
}
// 使用SmartLifecycle控制启动顺序
@Component
@Order(1)
class EarlyInitializer implements SmartLifecycle {
@Override
public void start() {
System.out.println("EarlyInitializer启动(优先级1)");
}
@Override
public int getPhase() {
return 0; // 阶段值越小,启动越早
}
}
@Component
@Order(2)
class LateInitializer implements SmartLifecycle {
@Override
public void start() {
System.out.println("LateInitializer启动(优先级2)");
}
@Override
public int getPhase() {
return 1; // 阶段值越大,启动越晚
}
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
11.3 Bean覆盖问题
less
@Configuration
public class BeanOverrideConfig {
// 主配置
@Primary // 标记为首选Bean
@Bean
public DataSource primaryDataSource() {
return createHikariDataSource();
}
// 备用配置
@Bean
@ConditionalOnMissingBean // 仅当没有DataSource Bean时才创建
public DataSource fallbackDataSource() {
return createSimpleDataSource();
}
// 使用@Qualifier区分同名Bean
@Bean(name = "masterDataSource")
public DataSource masterDataSource() {
return createMasterDataSource();
}
@Bean(name = "slaveDataSource")
public DataSource slaveDataSource() {
return createSlaveDataSource();
}
@Service
class DataSourceUser {
// 明确指定使用哪个Bean
@Autowired
@Qualifier("masterDataSource")
private DataSource masterDataSource;
@Autowired
@Qualifier("slaveDataSource")
private DataSource slaveDataSource;
}
}
AI写代码java
运行
12345678910111213141516171819202122232425262728293031323334353637383940
十二、Bean生命周期监控与调试
12.1 生命周期事件监听
typescript
@Component
public class BeanLifecycleListener implements ApplicationListener<ApplicationEvent> {
private static final Map<String, List<String>> beanLifecycleLogs = new ConcurrentHashMap<>();
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
System.out.println("容器刷新完成,共加载Bean: " +
((ContextRefreshedEvent) event).getApplicationContext().getBeanDefinitionCount());
} else if (event instanceof ContextStartedEvent) {
System.out.println("容器启动");
} else if (event instanceof ContextStoppedEvent) {
System.out.println("容器停止");
} else if (event instanceof ContextClosedEvent) {
System.out.println("容器关闭");
printLifecycleSummary();
} else if (event instanceof BeanDefinitionOverrideEvent) {
BeanDefinitionOverrideEvent overrideEvent = (BeanDefinitionOverrideEvent) event;
System.out.println("Bean定义覆盖: " + overrideEvent.getBeanName());
} else if (event instanceof ServletRequestHandledEvent) {
// 请求处理事件
ServletRequestHandledRequestEvent requestEvent = (ServletRequestHandledRequestEvent) event;
System.out.println("请求处理: " + requestEvent.getRequestUrl());
}
}
public static void logBeanLifecycle(String beanName, String lifecyclePhase) {
beanLifecycleLogs
.computeIfAbsent(beanName, k -> new ArrayList<>())
.add(lifecyclePhase + " @ " + System.currentTimeMillis());
}
private void printLifecycleSummary() {
System.out.println("\n=== Bean生命周期总结 ===");
beanLifecycleLogs.forEach((beanName, phases) -> {
System.out.println("\n" + beanName + ":");
phases.forEach(phase -> System.out.println(" " + phase));
});
}
}
// 自定义Bean后处理器来记录生命周期
@Component
public class LifecycleLoggingBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
BeanLifecycleListener.logBeanLifecycle(beanName, "BeforeInitialization");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
BeanLifecycleListener.logBeanLifecycle(beanName, "AfterInitialization");
return bean;
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
12.2 Bean生命周期可视化工具
scss
@Component
public class BeanLifecycleVisualizer {
@Autowired
private ConfigurableApplicationContext context;
/**
* 打印Bean的完整依赖图
*/
public void printBeanDependencyGraph() {
System.out.println("\n=== Bean依赖关系图 ===");
String[] beanNames = context.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = ((BeanDefinitionRegistry) context).getBeanDefinition(beanName);
System.out.printf("\n%s [%s]%n", beanName, beanDefinition.getBeanClassName());
System.out.println(" Scope: " + beanDefinition.getScope());
System.out.println(" Lazy: " + beanDefinition.isLazyInit());
System.out.println(" Primary: " + beanDefinition.isPrimary());
if (beanDefinition.getDependsOn() != null) {
System.out.println(" DependsOn: " + Arrays.toString(beanDefinition.getDependsOn()));
}
}
}
/**
* 分析Bean初始化时间
*/
public void analyzeInitializationTime() {
System.out.println("\n=== Bean初始化时间分析 ===");
Map<String, Long> initTimes = new HashMap<>();
// 可以通过自定义BeanPostProcessor记录时间
// 这里只是展示框架
initTimes.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.limit(10)
.forEach(entry ->
System.out.printf("%s: %d ms%n", entry.getKey(), entry.getValue())
);
}
/**
* 检测潜在的问题
*/
public void detectPotentialIssues() {
System.out.println("\n=== 潜在问题检测 ===");
String[] beanNames = context.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = ((BeanDefinitionRegistry) context).getBeanDefinition(beanName);
// 检测大对象
if (beanDefinition.getBeanClassName() != null &&
beanDefinition.getBeanClassName().contains("Cache") &&
!beanDefinition.isLazyInit()) {
System.out.println("警告: " + beanName + " 是大对象但未设置懒加载");
}
// 检测循环依赖
try {
Object bean = context.getBean(beanName);
// 实际检测需要更复杂的逻辑
} catch (Exception e) {
if (e.getMessage().contains("circular")) {
System.out.println("警告: " + beanName + " 可能存在循环依赖");
}
}
}
}
}
AI写代码java
运行
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
十三、总结与最佳实践
13.1 Bean生命周期关键点总结
| 阶段 | 关键方法/接口 | 执行时机 | 主要用途 |
|---|---|---|---|
| 实例化 | 构造器 | Bean创建时 | 对象创建、基础初始化 |
| 属性赋值 | @Autowired, @Value | 实例化后 | 依赖注入、配置注入 |
| Aware接口 | BeanNameAware等 | 属性赋值后 | 获取容器信息 |
| 前置处理 | BeanPostProcessor.before | Aware接口后 | 代理创建、属性修改 |
| 初始化 | @PostConstruct, afterPropertiesSet, init-method | 前置处理后 | 资源初始化、数据加载 |
| 后置处理 | BeanPostProcessor.after | 初始化后 | AOP代理、监控包装 |
| 使用期 | 业务方法 | 初始化完成后 | 业务处理 |
| 销毁 | @PreDestroy, destroy, destroy-method | 容器关闭时 | 资源释放、连接关闭 |
13.2 Bean生命周期最佳实践
-
构造器设计原则
kotlin// 推荐:使用构造器注入强制依赖 @Component public class OrderService { private final OrderRepository repository; private final PaymentService paymentService; @Autowired public OrderService(OrderRepository repository, PaymentService paymentService) { this.repository = repository; this.paymentService = paymentService; } } AI写代码java 运行 12345678910111213 -
初始化方法使用建议
less@Component public class DataSourceManager { @PostConstruct // 用于轻量级初始化 public void validateConfig() { // 配置验证 } @Override // 用于重量级初始化 public void afterPropertiesSet() { // 资源初始化 } @Bean(initMethod = "start") // 用于启动服务 public void start() { // 启动服务 } } AI写代码java 运行 123456789101112131415161718 -
销毁方法设计模式
less@Component public class ResourceHolder { @PreDestroy // 快速清理 public void preDestroy() { // 停止接收新请求 } @Override // 主要资源释放 public void destroy() { // 释放资源 } @Bean(destroyMethod = "cleanup") // 最终清理 public void cleanup() { // 清理残留 } } AI写代码java 运行 123456789101112131415161718 -
BeanPostProcessor使用规范
typescript@Component public class CustomProcessor implements BeanPostProcessor, Ordered { @Override public int getOrder() { // 明确指定执行顺序 return Ordered.LOWEST_PRECEDENCE - 10; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { // 前置处理 return wrapIfNeeded(bean, beanName); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { // 后置处理 return registerForMonitoring(bean, beanName); } } AI写代码java 运行 123456789101112131415161718192021
13.3 性能优化建议
-
合理使用作用域
less@Component @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) // 默认,适合无状态Bean public class UtilityService { ... } @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 适合有状态Bean public class RequestContext { ... } @Component @Scope(WebApplicationContext.SCOPE_REQUEST) // Web请求作用域 public class UserSession { ... } AI写代码java 运行 1234567891011 -
合理使用懒加载
less@Component @Lazy // 延迟初始化,提高启动速度 public class HeavyResourceService { // 资源密集型服务 } @Configuration public class Config { @Bean @Lazy // 配置级别的懒加载 public DataSource dataSource() { return createDataSource(); } } AI写代码java 运行 1234567891011121314 -
避免过早初始化
typescript@Configuration public class OptimizedConfig { // 错误:在@Configuration中直接调用Bean方法 // @Bean // public ServiceA serviceA() { // return new ServiceA(serviceB()); // 会导致serviceB过早初始化 // } // 正确:使用方法参数注入 @Bean public ServiceA serviceA(ServiceB serviceB) { return new ServiceA(serviceB); } @Bean @Lazy public ServiceB serviceB() { return new ServiceB(); } } AI写代码java 运行 123456789101112131415161718192021
13.4 常见陷阱与规避方法
-
构造器中的依赖使用
less@Component public class ProblematicBean { @Autowired private AnotherBean anotherBean; public ProblematicBean() { // 错误:在构造器中使用依赖 // anotherBean.doSomething(); // anotherBean为null // 正确:在@PostConstruct中使用 } @PostConstruct public void init() { anotherBean.doSomething(); // 此时依赖已注入 } } AI写代码java 运行 123456789101112131415161718 -
原型Bean中的单例依赖
less@Component @Scope("prototype") public class PrototypeBean { @Autowired private SingletonBean singletonBean; // 正确:单例注入原型 // 注意:原型Bean不会自动清理单例Bean的引用 // 如果单例Bean持有大数据,考虑使用WeakReference } @Component public class SingletonBean { @Autowired private ObjectProvider<PrototypeBean> prototypeBeanProvider; // 正确:通过Provider获取原型 public void usePrototype() { PrototypeBean prototype = prototypeBeanProvider.getObject(); // 使用原型Bean } } AI写代码java 运行 12345678910111213141516171819202122 -
Bean销毁顺序
kotlin@Configuration public class ShutdownOrderConfig { @Bean(destroyMethod = "shutdown") @Order(1) // 先关闭 public ExecutorService executorService() { return Executors.newFixedThreadPool(4); } @Bean(destroyMethod = "close") @Order(2) // 后关闭 public DataSource dataSource() { return createDataSource(); } // 注意:依赖关系会影响销毁顺序 // 被依赖的Bean会后销毁 } AI写代码java 运行 123456789101112131415161718
十四、结语
Spring Bean生命周期是Spring框架的核心机制,深入理解每个阶段的执行时机和扩展点,能够帮助我们:
- 构建更健壮的应用程序:合理管理资源生命周期,避免内存泄漏和资源竞争
- 实现更灵活的扩展:通过BeanPostProcessor等扩展点实现自定义逻辑
- 优化应用性能:合理使用懒加载、作用域等特性提升性能
- 快速定位问题:理解生命周期有助于快速排查Bean相关的问题
掌握Bean生命周期不仅是使用Spring框架的基础,更是深入理解IoC容器设计思想的关键。在实际开发中,应根据具体场景选择合适的生命周期回调方法,遵循最佳实践,构建高质量的企业级应用。