Spring Bean的生命周期
一、BeanDefinition阶段(Bean还没出生)
Spring启动时第一件事不是创建对象,而是解析配置生成 BeanDefinition。
BeanDefinition 本质就是:
Bean 的说明书
里面记录:
bean 的 class
scope(singleton / prototype)
依赖关系
initMethod
destroyMethod
举个直觉例子:
1 | UserService.class |
Spring 会把这些信息先放到 BeanDefinitionMap 里。
这一步其实就是:
扫描 → 解析 → 注册BeanDefinition
此时 对象还没创建。
二、实例化 Bean(构造函数阶段)
接下来 Spring 才开始创建对象:
new UserService()
这个阶段只做一件事:
调用构造函数
所以如果你写:
1 | public UserService() { |
这里就会执行。
但注意一个关键点:
此时 依赖还没有注入。
对象只是一个空壳。
三、依赖注入(DI)
接下来 Spring 会给 bean 填充依赖。
比如:
1 | @Service |
Spring 会执行类似逻辑:
1 | orderService.userService = userService |
这一步叫:
populateBean
也就是:
属性填充
常见方式:
1 | - @Autowired |
到这里:
1 | bean = 已创建 + 已注入依赖 |
四、Aware接口回调(获取Spring环境)
接下来 Spring 会检测 bean 是否实现了一些 Aware接口。
如果实现了,就回调对应方法。
常见三个:
BeanNameAware
1 | setBeanName(String name) |
可以知道自己的 beanName。
BeanFactoryAware
1 | setBeanFactory(BeanFactory factory) |
可以拿到 BeanFactory。
ApplicationContextAware
1 | setApplicationContext(ApplicationContext context) |
可以拿到 Spring 上下文。
这一步本质是:
Spring 把自己的一些核心对象告诉 Bean
五、初始化阶段(重点)
初始化阶段其实分 三小步,但可以作为一个整体记。
顺序是:
1 | BeanPostProcessor.before |
我们逐个看。
1 BeanPostProcessor before
Spring 会执行:
postProcessBeforeInitialization()
这是一个扩展点。
很多框架都会在这里做事。
2 初始化方法
有两种方式:
InitializingBean
afterPropertiesSet()
例如:
1 | public class UserService implements InitializingBean { |
自定义 init-method
@Bean(initMethod=”init”)
或
@PostConstruct
这一步通常用来:
初始化资源
建立连接
校验配置
3 BeanPostProcessor after
接下来执行:
postProcessAfterInitialization()
这一步非常关键。
AOP 就是在这里发生的。
六、AOP代理创建(Spring最核心魔法)
在 postProcessAfterInitialization 阶段:
Spring 会检查:
这个 Bean 是否需要 AOP
比如:
@Transactional
@Async
@Cacheable
自定义切面
如果需要,Spring不会直接返回原始对象,而是:
生成代理对象
代理类型有两种:
JDK 动态代理
条件:
bean 实现了接口
代理接口。
CGLIB
条件:
没有接口
Spring 会生成子类代理。
所以最终容器里的 bean 其实是:
代理对象
而不是原始对象。
这也是为什么:
AOP 本质 = 动态代理
七、Bean开始工作
到这里 Bean 生命周期就结束了。
之后应用运行时:
1 | Controller → Service → DAO |
调用的其实是:
代理对象
所以 AOP 才能拦截方法。
八、Bean销毁阶段(容器关闭)
当 Spring 容器关闭时,会执行销毁逻辑。
顺序:
1 | @PreDestroy |
例如:
关闭数据库连接
释放资源