bean的生命周期就是指,在spring中bean是如何创建,如何销毁的。
Bean的生成过程
1、生成BeanDefinition
首先Spring会进行包的扫描,将beanDefinitition存入Set集合。
spring扫描的过程大致如下。
- 首先,通过ResourcePatternResolver获得指定包路径下的所有 .class 文件(Spring源码中将 此文件包装成了Resource对象)
- 遍历每个Resource对象
- 利用MetadataReaderFactory解析Resource对象得到MetadataReader(用于获取类的元数据信息例如名字、实现了哪些接口等等)
- 利用MetadataReader进行excludeFilters和includeFilters,以及条件注解@Conditional的筛选
- 筛选通过后,基于metadataReader生成ScannedGenericBeanDefinition
- 再基于metadataReader判断是不是对应的类是不是接口或抽象类
- 如果筛选通过,那么就表示扫描到了一个Bean,将ScannedGenericBeanDefinition加入结果集
2、合并BeanDefinitition
什么是合并呢?举个例子。
<bean id="parent" class="com.zhouyu.service.Parent" scope="prototype"/>
<bean id="child" class="com.zhouyu.service.Child" parent="parent"/>
如上述代码,bean之间可以通过parent属性进行继承,该例子中,child继承了parent,所以child类型也是prototype。所以这一步需要进行beandefinition的合并,得到child对应的beandefinition的完整属性。
3、类加载
BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化就 必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的 createBean()方法中,一开始就会调用:
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
以上这行代码就是加载类的代码,点进去实现如下。
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null)
{
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ‐> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载 (doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用 **ClassUtils.getDefaultClassLoader()**所返回的类加载器来加载。
那么它返回什么呢?
- 优先返回当前线程中的ClassLoader
- 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
- 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么 则返回系统类加载器。
4、实例化前
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean 实例化之前做一些启动动作。这个扩展点叫 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。比如
@Component
public class ZhouyuBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("实例化前");
}
return null;
}
}
如上代码会导致,在userService这个Bean实例化前,会进行打印。
值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:
userService这个Bean,在实例化前会直接返回一个由我们所定义的UserService对象。如果是这样, 表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执 行初始化后这一步。
5、实例化
5.1 Supplier创建对象
5.2 工厂方法创建对象
5.3 推断构造方法
6. BeanDefinition的后置处理
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又 提供了一个扩展点 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的 BeanDefinition进行加工,大致实现跟上文介绍的那个扩展点类似,这里就不重复说明了。
7、实例化后
在处理完BeanDefinition后,Spring又设计了一个扩展点: InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
8、自动注入
这里的自动注入指的是Spring的自动注入,后续会说到。
9、处理属性
这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过 **InstantiationAwareBeanPostProcessor.postProcessProperties()**扩展点来实现的
10、执行Aware
- BeanNameAware:回传beanName给bean对象。
- BeanClassLoaderAware:回传classLoader给bean对象。
- BeanFactoryAware:回传beanFactory给对象。
11、初始化前
初始化前,也是Spring提供的一个扩展点:
BeanPostProcessor.postProcessBeforeInitialization()
12、初始化
- 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet() 方法
- 执行BeanDefinition中指定的初始化方法
13、初始化后
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点: BeanPostProcessor.postProcessAfterInitialization(),可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返 回的对象才是最终的Bean对象。
—参考周瑜大佬笔记