副标题:掌握Bean的一生,成为Spring高手!🎯
🎬 开场:Bean的一生
Bean的故事
一个Bean的自述:
大家好,我是一个Spring Bean 👋
我的一生经历了:
┌──────────────────────────────────┐
│ 1. 出生(实例化) │
│ 2. 填充属性(依赖注入) │
│ 3. 初始化(各种回调) │
│ 4. 工作(被使用) │
│ 5. 销毁(清理资源) │
└──────────────────────────────────┘
这个过程中,Spring提供了N个扩展点,
让你可以在我生命的各个阶段插手干预!
让我们一起来看看我这精彩的一生吧!🎭
📚 完整生命周期
生命周期总览
Spring Bean生命周期(11个步骤):
1️⃣ 实例化(Instantiation)
↓
2️⃣ 设置属性(Populate Properties)
↓
3️⃣ BeanNameAware.setBeanName()
↓
4️⃣ BeanFactoryAware.setBeanFactory()
↓
5️⃣ ApplicationContextAware.setApplicationContext()
↓
6️⃣ BeanPostProcessor.postProcessBeforeInitialization()
↓
7️⃣ @PostConstruct / InitializingBean.afterPropertiesSet()
↓
8️⃣ 自定义init-method
↓
9️⃣ BeanPostProcessor.postProcessAfterInitialization()
↓
🔟 Bean ready for use(可以使用了)
↓
1️⃣1️⃣ @PreDestroy / DisposableBean.destroy() / destroy-method
🔍 详细步骤解析
步骤1:实例化(Instantiation)
/**
* Bean的诞生!
*
* Spring通过反射调用构造器创建Bean实例
*/
public class UserService {
public UserService() {
System.out.println("1️⃣ 构造器被调用,Bean实例化");
}
}
// Spring内部:
Class<?> clazz = UserService.class;
Constructor<?> constructor = clazz.getConstructor();
Object bean = constructor.newInstance(); // 👶 Bean诞生了!
扩展点:InstantiationAwareBeanPostProcessor
/**
* 在实例化前后进行干预
*/
@Component
public class MyInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
/**
* 实例化之前调用
*
* 可以返回代理对象,阻止默认实例化
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
System.out.println("1.1 实例化之前: " + beanName);
// 返回null表示使用默认实例化
return null;
}
/**
* 实例化之后调用
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
System.out.println("1.2 实例化之后: " + beanName);
// 返回true表示继续后续处理
return true;
}
}
步骤2:设置属性(Populate Properties)
/**
* Bean获得它的朋友们(依赖注入)
*/
@Service
public class UserService {
@Autowired
private UserMapper userMapper; // 注入依赖
@Value("${app.name}")
private String appName; // 注入配置
public UserService() {
System.out.println("1️⃣ 构造器:userMapper = " + userMapper);
// 输出:null(还没注入)
}
@PostConstruct
public void init() {
System.out.println("7️⃣ 初始化:userMapper = " + userMapper);
// 输出:UserMapper实例(已注入)
}
}
属性注入过程:
Spring内部处理:
1. 扫描@Autowired、@Resource、@Value注解
2. 解析依赖
3. 从容器中查找依赖的Bean
4. 通过反射设置字段值
Field field = UserService.class.getDeclaredField("userMapper");
field.setAccessible(true);
field.set(userServiceInstance, userMapperInstance);
步骤3-5:Aware接口回调
/**
* Bean认识自己和环境
*/
@Component
public class MyBean implements
BeanNameAware, // 知道自己的名字
BeanFactoryAware, // 知道Bean工厂
ApplicationContextAware // 知道应用上下文
{
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
/**
* 3️⃣ BeanNameAware:Bean知道自己叫什么
*/
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("3️⃣ 我知道我叫: " + name);
}
/**
* 4️⃣ BeanFactoryAware:Bean知道自己的工厂
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
System.out.println("4️⃣ 我知道我的工厂: " + beanFactory.getClass().getSimpleName());
}
/**
* 5️⃣ ApplicationContextAware:Bean知道应用上下文
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
System.out.println("5️⃣ 我知道应用上下文: " + applicationContext.getClass().getSimpleName());
// 现在可以从容器获取其他Bean了
UserService userService = applicationContext.getBean(UserService.class);
}
}
Aware接口家族:
Spring提供的Aware接口:
BeanNameAware → 获取Bean名称
BeanFactoryAware → 获取BeanFactory
ApplicationContextAware → 获取ApplicationContext
EnvironmentAware → 获取Environment
ResourceLoaderAware → 获取ResourceLoader
ApplicationEventPublisherAware → 获取事件发布器
MessageSourceAware → 获取国际化资源
ServletContextAware → 获取ServletContext(Web应用)
步骤6:BeanPostProcessor.postProcessBeforeInitialization()
/**
* 初始化之前的扩展点
*
* 这是最重要的扩展点之一!
* Spring的很多功能都在这里实现:
* - @Autowired注解处理
* - @Value注解处理
* - @PostConstruct注解处理
* - AOP代理创建
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 6️⃣ 初始化之前
*
* 可以修改Bean实例
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("6️⃣ 初始化之前: " + beanName);
// 示例:给所有Bean添加创建时间
if (bean instanceof BaseEntity) {
((BaseEntity) bean).setCreateTime(new Date());
}
return bean;
}
/**
* 9️⃣ 初始化之后
*
* 可以返回代理对象
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("9️⃣ 初始化之后: " + beanName);
// 示例:创建AOP代理
if (needProxy(bean)) {
return createProxy(bean);
}
return bean;
}
}
Spring内置的BeanPostProcessor:
Spring内置了很多BeanPostProcessor:
1. CommonAnnotationBeanPostProcessor
- 处理@PostConstruct
- 处理@PreDestroy
- 处理@Resource
2. AutowiredAnnotationBeanPostProcessor
- 处理@Autowired
- 处理@Value
- 处理@Inject
3. ApplicationContextAwareProcessor
- 处理各种Aware接口
4. AnnotationAwareAspectJAutoProxyCreator
- 创建AOP代理
步骤7-8:初始化方法
/**
* Bean的初始化
*
* 三种方式,执行顺序:
* 1. @PostConstruct
* 2. InitializingBean.afterPropertiesSet()
* 3. init-method
*/
@Component
public class UserService implements InitializingBean {
@Autowired
private UserMapper userMapper;
/**
* 7️⃣.1 @PostConstruct(推荐)
*
* JSR-250标准注解
*/
@PostConstruct
public void postConstruct() {
System.out.println("7️⃣.1 @PostConstruct执行");
// 此时所有依赖都已注入
System.out.println("userMapper已注入: " + (userMapper != null));
// 可以做初始化工作
loadCache();
}
/**
* 7️⃣.2 InitializingBean.afterPropertiesSet()
*
* Spring接口,不推荐(耦合Spring)
*/
@Override
public void afterPropertiesSet() {
System.out.println("7️⃣.2 afterPropertiesSet()执行");
}
/**
* 8️⃣ 自定义init-method
*
* 通过@Bean(initMethod="init")指定
*/
public void init() {
System.out.println("8️⃣ 自定义init-method执行");
}
private void loadCache() {
System.out.println("加载缓存数据...");
}
}
// 配置类中指定init-method
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public UserService userService() {
return new UserService();
}
}
步骤9:BeanPostProcessor.postProcessAfterInitialization()
/**
* 初始化之后的扩展点
*
* AOP代理就是在这里创建的!
*/
@Component
public class AopProxyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 检查是否需要创建代理
if (needAopProxy(bean)) {
System.out.println("9️⃣ 为Bean创建AOP代理: " + beanName);
// 创建JDK动态代理或CGLIB代理
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理方法执行: " + method.getName());
// 执行原方法
return method.invoke(bean, args);
}
}
);
}
return bean;
}
}
步骤10:Bean可以使用了
/**
* 🔟 Bean已经完全初始化,可以使用了!
*/
@Service
public class OrderService {
@Autowired
private UserService userService; // 已完全初始化的Bean
public void createOrder() {
// 使用Bean
User user = userService.getUser(1L);
// ...
}
}
步骤11:销毁
/**
* Bean的死亡
*
* 三种方式,执行顺序:
* 1. @PreDestroy
* 2. DisposableBean.destroy()
* 3. destroy-method
*/
@Component
public class UserService implements DisposableBean {
/**
* 1️⃣1️⃣.1 @PreDestroy(推荐)
*/
@PreDestroy
public void preDestroy() {
System.out.println("1️⃣1️⃣.1 @PreDestroy执行");
// 清理资源
closeConnections();
}
/**
* 1️⃣1️⃣.2 DisposableBean.destroy()
*/
@Override
public void destroy() {
System.out.println("1️⃣1️⃣.2 destroy()执行");
}
/**
* 1️⃣1️⃣.3 自定义destroy-method
*/
public void cleanup() {
System.out.println("1️⃣1️⃣.3 自定义destroy-method执行");
}
private void closeConnections() {
System.out.println("关闭连接...");
}
}
@Configuration
public class AppConfig {
@Bean(destroyMethod = "cleanup")
public UserService userService() {
return new UserService();
}
}
🎨 完整示例
示例代码
/**
* 完整的Bean生命周期示例
*/
@Component
public class LifecycleBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private String beanName;
@Autowired
private UserService userService;
// 1️⃣ 构造器
public LifecycleBean() {
System.out.println("1️⃣ 构造器执行");
}
// 2️⃣ 属性注入(在构造器之后)
// Spring自动注入userService
// 3️⃣ BeanNameAware
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("3️⃣ setBeanName: " + name);
}
// 4️⃣ BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("4️⃣ setBeanFactory");
}
// 5️⃣ ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("5️⃣ setApplicationContext");
}
// 6️⃣ BeanPostProcessor.postProcessBeforeInitialization()
// (由BeanPostProcessor执行,不在Bean中)
// 7️⃣.1 @PostConstruct
@PostConstruct
public void postConstruct() {
System.out.println("7️⃣.1 @PostConstruct");
}
// 7️⃣.2 InitializingBean.afterPropertiesSet()
@Override
public void afterPropertiesSet() {
System.out.println("7️⃣.2 afterPropertiesSet");
}
// 8️⃣ init-method(通过@Bean(initMethod="init")指定)
public void init() {
System.out.println("8️⃣ init-method");
}
// 9️⃣ BeanPostProcessor.postProcessAfterInitialization()
// (由BeanPostProcessor执行,不在Bean中)
// 🔟 Bean可以使用了
// 1️⃣1️⃣.1 @PreDestroy
@PreDestroy
public void preDestroy() {
System.out.println("1️⃣1️⃣.1 @PreDestroy");
}
// 1️⃣1️⃣.2 DisposableBean.destroy()
@Override
public void destroy() {
System.out.println("1️⃣1️⃣.2 destroy");
}
// 1️⃣1️⃣.3 destroy-method(通过@Bean(destroyMethod="cleanup")指定)
public void cleanup() {
System.out.println("1️⃣1️⃣.3 destroy-method");
}
}
运行结果
1️⃣ 构造器执行
1.1 实例化之前: lifecycleBean
1.2 实例化之后: lifecycleBean
2️⃣ 属性注入(自动)
3️⃣ setBeanName: lifecycleBean
4️⃣ setBeanFactory
5️⃣ setApplicationContext
6️⃣ postProcessBeforeInitialization: lifecycleBean
7️⃣.1 @PostConstruct
7️⃣.2 afterPropertiesSet
8️⃣ init-method
9️⃣ postProcessAfterInitialization: lifecycleBean
🔟 Bean可以使用了
--- 应用关闭 ---
1️⃣1️⃣.1 @PreDestroy
1️⃣1️⃣.2 destroy
1️⃣1️⃣.3 destroy-method
🎯 常见应用场景
场景1:初始化缓存
@Component
public class CacheService {
private Map<String, Object> cache = new ConcurrentHashMap<>();
/**
* 应用启动时加载缓存
*/
@PostConstruct
public void initCache() {
log.info("开始加载缓存...");
// 从数据库加载数据
List<Config> configs = configMapper.selectAll();
for (Config config : configs) {
cache.put(config.getKey(), config.getValue());
}
log.info("缓存加载完成,共{}条", cache.size());
}
/**
* 应用关闭时清理缓存
*/
@PreDestroy
public void clearCache() {
log.info("清理缓存...");
cache.clear();
}
}
场景2:数据库连接池
@Component
public class DataSourceManager implements DisposableBean {
private DataSource dataSource;
@PostConstruct
public void initDataSource() {
log.info("初始化数据源...");
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10);
dataSource = new HikariDataSource(config);
log.info("数据源初始化完成");
}
@Override
public void destroy() {
log.info("关闭数据源...");
if (dataSource instanceof HikariDataSource) {
((HikariDataSource) dataSource).close();
}
log.info("数据源已关闭");
}
}
场景3:定时任务初始化
@Component
public class ScheduledTaskManager {
@Autowired
private TaskScheduler taskScheduler;
private ScheduledFuture<?> scheduledTask;
@PostConstruct
public void startScheduledTask() {
log.info("启动定时任务...");
scheduledTask = taskScheduler.scheduleAtFixedRate(() -> {
log.info("执行定时任务");
// 业务逻辑
}, 60000); // 每分钟执行一次
log.info("定时任务已启动");
}
@PreDestroy
public void stopScheduledTask() {
log.info("停止定时任务...");
if (scheduledTask != null) {
scheduledTask.cancel(false);
}
log.info("定时任务已停止");
}
}
🎉 总结
生命周期口诀
Bean生命周期要记牢,
十一个步骤不能少。
构造器里Bean诞生,
属性注入交朋友。
三个Aware知环境,
名字工厂和上下文。
前置处理做准备,
PostConstruct先执行。
afterPropertiesSet跟上,
自定义init最后到。
后置处理做代理,
AOP就在这里弄。
Bean准备好可以用,
工作一生为人民。
应用关闭要销毁,
PreDestroy先执行。
DisposableBean紧跟上,
destroy-method收尾好!
推荐实践
1. 初始化方法选择:
推荐:@PostConstruct ⭐⭐⭐⭐⭐
原因:标准、简单、不耦合Spring
2. 销毁方法选择:
推荐:@PreDestroy ⭐⭐⭐⭐⭐
原因:标准、简单、不耦合Spring
3. Aware接口:
必要时使用:ApplicationContextAware
不推荐:其他Aware(用@Autowired替代)
4. BeanPostProcessor:
框架开发者使用
应用开发者很少需要
关键扩展点
1. BeanPostProcessor
- 最强大的扩展点
- AOP、事务、校验都基于此
2. @PostConstruct / @PreDestroy
- 最常用的扩展点
- 初始化和清理资源
3. ApplicationContextAware
- 获取ApplicationContext
- 动态获取Bean
4. BeanFactoryPostProcessor
- 修改BeanDefinition
- 修改Bean配置元数据
愿你的Bean生命精彩,Spring之路一帆风顺! 🌱✨