Spring Bean 生命周期
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans。
BeanDefinition
Bean定义,最常见方式有两种,xml方式和java注解方式。
一个bean定义有以下9种属性:
- Class :定义bean的 class 名字。
- Name:定义bean的名称
- Scope:定义bean的作用域
- Constructer Arguments:定义使用的构造方法
- Properties:属性
- Autowired Mode:注入模型
- Lazy initialization mode:懒加载
- Initialization method:初始化方法
- Destruction method:销毁方法
|
|
打印出的是Horse,这就是指鹿为马。
再联想一下,mybatis为什么只写Mapper接口就能进行dao操作?我们知道接口是无法实例化的。
没错,mybatis就是在这点进行了扩展,通过修改mapper的bean定义中的class属性,把 mapper 的 GenericBeanDefinition 的 class 修改成了一个 MapperFactoryBean,从而实现了mapper的代理类。
Autowired Mode(注入模型)
注入模型分为四种,分别是
-
no:不注入,这也是默认的选项。意味着如果我们不在某个字段上标记@Autowired等标签,spring就把该字段当做是普通字段,不会进行自动注入。
-
byName:在容器中寻找和属性同名的bean进行注入。
-
byType:在容器中寻找字段的class的bean并注入。 AbstractBeanDefinition.AUTOWIRE_BY_TYPE
-
constructor:和byType相似,只不过是在构造函数上注入。
Bean 扫描
bean定义最后都会放到BeanFactory的beanDefinitionMap中去。
BeanFactoryPostProcessor
在spring容器启动时,加载我们的bean定义后,来到spring提供的第一个扩展点!那就是BeanFactoryPostProcessor。
BeanFactoryPostProcessor允许我们读取bean的配置信息,然后在spring初始化bean之前去修改bean定义。
只需要实现该接口,并添加到容器中,spring就会执行实现的方法,进行你需要的增强。
BeanFactoryPostProcessor只有一个方法需要实现 postProcessBeanFactory,在这个方法中我们可以根据传递过来的beanfactory来获取想要修改的bean定义。正如我们之前修改的注入模型和class时候做的。
实例化
实例化意味着执行构造方法。
在refresh方法的finishBeanFactoryInitialization方法中,会对所有的单例非懒加载的bean进行创建,实例化便是其中步骤之一。
首先会先去获取bean,不存在就创建bean,解决循环依赖等。
如果你不知道bean是在哪个方法实例化的,那么你就打断点在构造方法上,毕竟只要实例化,无论是反射也好new也罢,都会走构造方法。
注意实例化是初始化的区别,实例化仅仅是调用构造方法进行对象的创建,不包含属性的赋值等初始化方法。
属性赋值
在上一步对象构造完之后,对象内的属性还没有进行赋值。
|
|
初始化
把初始化前置增强,初始化,初始化后置增强,统一归为初始化
自定义初始化的操作,这里我们还可以进行扩展,通过实现BeanPostProcessor接口。
当然init方法我们也是可以定义!可以通过实现InitializingBean接口,或者在初始化方法上添加@PostConstruct注解。
|
|
总结
- bean 定义
- bean定义被spring解析
- post process bean factory
- Constructs with no arg
- before initialization
- post construct (init)
- after initialization
- pre destory
针对 spring bean生命周期,推荐结合spring的官方文档和代码断点调试,来彻底理解整个生命周期,以及我们能对其做怎样的扩展。