文章目录
生命周期图
Bean生命周期含义:在Spring中,一个Bean是如何生成的,如何销毁的

Bean扫描


Bean 的创建过程
1. 生成BeanDefinition
- 通过
ResourcePatternResolver获取指定路径下所有的.class文件(封装为Resource对象) - 遍历所有
Resource对象 - 利用
MetadataReaderFactory(具体实现类:CachingMetadataReaderFactory)解析Resource对象获得MetadataReader(具体实现类:SimpleMetadataReader) - 通过
MetadataReader来进行excludeFilters和includeFilters过滤,并通过条件注解@Condition进行筛选(如果有@Condition注解则调用match()方法进行匹配筛选) - 基于
metadataReader生成对应的ScannedGenericBeanDefination - 再次基于
metadataReader进行筛选(判断是否为非顶级类、非静态内部类、接口、抽象类等) - 通过筛选的类,将其
ScannedGenericBeanDefinition加入结果集(扫描到一个Bean)
除了扫描生成BeanDefinition对象之外,还可以通过直接定义BeanDefinition,或解析spring.xml配置文件中的<bean/>,或用@Bean注解得到BeanDefinition对象。
MetadataReader 作用
- 类名
- 父类名
- 所有实现的接口名
- 所有内部类名
- 是否为抽象类
- 是否为接口
- 是否是一个注解
- 获取已有的注解的所有方法集合
- 获取所有注解信息
- 获取所有注解类型集合
CachingMetadataReaderFactory解析.class文件得到的MetadataReader对象是通过ASM技术获取的,并未去加载这个类!!!
得到的SccannedGenericBeanDefinition对象中,beanClass属性存储的只是当前类的名字,并非class对象! (beanClass属性的类型为Object,既可以存储类的名字(String),也可以存储class对象(Class<?>))
2.合并BeanDefinition
在 Spring 中,支持父子 BeanDefinition!
可以通过父子BeanDefinition继承一些属性。
<bean id="parent" class="Parent" scope="prototype"/>
<bean id="child" class="Child" parent="parent"/>
在该例子中,由于 child 指定父亲 BeanDefinition 为 parent ,因此继承 parent 中的 scope 属性的值 prototype。
而在根据 child 来生成 Bean 对象之前,需要进行 BeanDefinition 的合并,才能得到完整的 child 的 BeanDefinition。
-> MergedBeanDefinition
3.加载类
合并 BeanDefinition 后便可以创建 Bean 对象,而创建 Bean 对象就必须要 实例化 对象, 因此需要先加载当前 BeanDefinition 对应的 class 。
AbstractAutowireCapableBeanFactory 的 createBean() 方法中:
Class<?> resolvedClass = resolveBeanClass(mdb, beanName);
resolveBeanClass() 方法便是去加载类的。
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ‐>
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
} else {
return doResolveBeanClass(mbd, typesToMatch);
}
hasBeanClass() :
判读 beanClass 属性是否为 Class 实例(是否被加载过)
public boolean hasBeanClass() {
return (this.beanClass instance Class);
}
会使用 BeanFactory 所设置的类加载器来加载类,如果没有设置类加载器,则默认使用 ClassUtils.getDefaultClassLoader() 返回的类加载器来加载。
ClassUtils.getDefaultClassLoader()
- 优先返回当前线程中的 ClassLoader
- 线程中类加载器为 null 时,返回 ClassUtils 类的类加载器
- 如果 ClassUtils 类的类加载器为 null ,则表示由 Bootsrap 类加载器加载的 ClassUtils 类,那么直接返回系统类加载器
4.实例化前
在类被加载后,实例化前,Spring 提供了一个扩展点,允许用户来控制是否在某个或某些 Bean 实例化前做一些启动动作。
扩展点:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
实现 InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法
/**
当每有一个 Bean 对象实例化前,会打印 “实例化前”
*/
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
System.out.println("实例化前");
return null;
}
}
注意:
postProcessBeforeInstantiation() 是有返回值的,如果返回非空对象,则会在实例化前直接返回我们返回的对象。如果这样做,则表示不需要再由 Spring 来实例化,并且后续的 Spring 依赖注入也不会再进行!直接执行初始化后这一阶段。
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
5.实例化
5.1 Supplier 创建对象
首先检测 BeanDefinition 中是否设置了 Supplier ,如果存在则调用 Supplier 的 get() 方法获取对象。
// BeanDefinition中添加了Supplier,则调用Supplier来得到对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
5.2 工厂方法创建对象
如果没有设置 Supplier ,则检查 BeanDefinition 中是否设置了 factoryMethod,也就是工厂方法。(两种设置 factoryMethod的方式)
// @Bean对应的BeanDefinition
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
方式一: 指定 factoryMethod 为当前类的方法
<bean id="userService" class="UserService" factory‐
method="createUserService" />
对应的 UserService 类:
public class UserService {
public static UserService createUserService() {
System.out.println("执行createUserService()");
UserService userService = new UserService();
return userService;
}
}
方式二: 指定 factoryMedthod 为其他类的方法
<bean id="commonService" class="CommonService"/>
<bean id="userService" factory‐bean="commonService" factory‐method="createUserService"
/>
对应的 CommonService 类:
public class CommonService {
public UserService createUserService() {
return new UserService();
}
}
若设置了 工厂方法,则 Spring 会调用工厂方法获取对象。
注意:
如果通过 @Bean 注解定义的 BeanDefinition,也是存在 factoryMethod 和 factoryBean 的!与 方式二 类似,@Bean 所注解的方法就是 factoryMetod, 所在的类的对象就是 factoryBean。 如果 @Bean 所注解的方法是 static 的,则对应 方式一。
5.3 推断构造方法
根据传入的参数推断使用的构造方法,用它来实例化。
在推断构造方法逻辑中,除去选择构造方法与查找入参对象之外,还会判断是否在对应的类中是否存在 @Lookup 注解的方法。 如果存在,则把该方法封装为 LookupOverride 对象并添加到 BeanDefinition 中。
在实例化时,如果当前 BeanDefinition 中存在 LookupOverride 对象(该类存在 @Lookup注解了的方法)则会生成一个 代理对象;否则直接反射调用构造方法获取一个实例对象。
@Looup 注解就是 方法注入
@Component
public class UserService {
private OrderService orderService;
public void test() {
OrderService orderService = createOrderService();
System.out.println(orderService);
}
@Lookup("orderService")
public OrderService createOrderService() {
return null;
}
}
6. BeanDefinition 的后置处理
实例化 Bean 之后,接下来需要给对象属性赋值。在真正给属性赋值之前, Spring 提供了一个扩展点
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
可以对当前的 BeanDefinition 加工!
在 Spring 源码中,AutowiredAnnotationBeanPostProcessor 就是一个 JMergedBeanDefinitionPostProcessor,它的 postProcessMergedBeanDefinition() 会去查找注入点,并缓存在 AutowiredAnnotationBeanPostProcessor 对象的一个 Map 中(injectionMetadataCache)。
7.实例化后
在处理完 BeanDefinition 后,Spring还提供了一个扩展点:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
返回值类型为 boolean,如果返回 false 则会结束后续的postProcessAfterInstantitaion()和postProcessPropertiesValues()的执行!!!
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
但是该扩展点在 Spring 中基本没有被使用到。
8.自动注入
9.处理属性
处理 @Autowired 、@Resource 、@Value 等注解,都是通过实现 InstantiationAwareBeanPostProcessor.postProcessProperties() 扩展点来实现的。
这个方法通常是给目标 bean 设值,这个过程发生只有在postProcessAfterInstantiation() 方法的结果返回 true 才会被执行!
@Component
public class MyInstantiationAwareBeanPostProcessor implements
InstantiationAwareBeanPostProcessor {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
for (Field field : bean.getClass().getFields()) {
if (field.isAnnotationPresent(ZhouyuInject.class)) {
field.setAccessible(true);
try {
field.set(bean, "123");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return pvs;
}
}
在 AbstractAutowireCapableBeanFactory 类的方法 populateBean 中会执行到该扩展点:
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds =
filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds,
bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
可以看到,如果这个方法返回为空,也不会对目标bean设值
10. 执行部分 Aware
在完成属性赋值后,Spring 还会调用一些列实现了 Aware 接口的回调方法。
- BeanNameAware: 将 beanName 注入到 bean 对象中
- BeanClassLoaderAware: 将 classLoader 注入到 bean 对象中
- BeanFactoryAware
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
11. 初始化前
在初始化前 Spring 提供了一个扩展点:
BeanPostProcessor.postProcessBeforeInitialization()
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
返回值:可以是原始的Bean实例,也可以是包装的Bean实例;如果为空,则不会调用后续的 BeanPostProcessors 的 postProcessBeforeInitialization() 方法!
@PostConstruct
InitDestroyAnnotationBeanPostProcessor 会在初始前执行有 @PostConstruct 注解的方法。
ApplicationContextAwareProcessor
ApplicationContextAwareProcessor 会在初始化前进行其他 Aware 的回调。
- EnvironmentAware:回传环境变量
- EmbeddedValueResolverAware:回传占位符解析器
- ResourceLoaderAware:回传资源加载器
- ApplicationEventPublisherAware:回传事件发布器
- MessageSourceAware:回传国际化资源
- ApplicationStartupAware:回传应用其他监听对象,可忽略
- ApplicationContextAware:回传Spring容器ApplicationContext
12. 初始化
InitializingBean
如果 Bean 对象实现了 InitializingBean 接口,则调用其 afterPropertiesSet() 方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
BeanDefinition 中指定的初始化方法
执行 BeanDefinition 中指定的初始化方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
13. 初始化后
这是 Bean 创建生命周期中的最后一个步骤,也是 Spring 提供的一个扩展点
BeanPostProcessor.postProcessAfterInitialization()
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
若返回 null ,则会提前结束,取消执行后续的 BeanPostProcessor 的 postProcessAfterInitialization() 方法!
Bean 的销毁过程
Bean 销毁是发生在 Spring 容器关闭过程中的。context.close()
判断是否属于 DisposableBean
在 Bean 创建过程中,初始化后,会去判断当前创建的 Bean 是否属于 DisposableBean
- 是否实现
DisposableBean接口 - 是否实现
AutoCloseable接口 - BeanDefinition 中是否指定了 destroyMethod
- DestructionAwareBeanPostProcessor.requiresDestruction(bean) 中判断
- ApplicationListenerDetector:是否实现
ApplicationListener - InitDestroyAnnotationBeanPostProcessor: 检测是否有
@PreDestroy注解的方法
- ApplicationListenerDetector:是否实现
- 将符合以上任意一个条件的 Bean 适配成 DisposableBeanAdapter 对象,并存储在 disposableBeans 中(一个 LinkedHashMap)
销毁过程
- 首先发布 ContextClosedEvent 事件
- 调用 lifecycleProcessor 的 onClose() 方法
- 销毁单例 Bean
- 遍历 disposableBeans
- 把每个 disposableBean 从单例池中移除
- 调用 disposableBean 的 destroy()
- 如果该 disposableBean 被其他 Bean 依赖,则同时销毁其他 Bean
- 如果该 disposableBean 包含 inner beans ,则将这些 Bean 从单例池中移除
- 清空 manualSingletonNames(存储着 用户手动注册 的单例 Bean 的 beanName 的 Set)
- 清空 allBeanNamesByType(Map<Class<?>,String[]>)
- 清空 singletonBeanNamesByType(只存储了单例Bean)
- 遍历 disposableBeans
本文详细阐述了Spring中Bean的生命周期,从BeanDefinition的生成、Bean的创建过程(包括生成、合并、加载类、实例化前、实例化、BeanDefinition后置处理等步骤)到Bean的销毁过程,揭示了Spring如何管理Bean的整个生命周期。内容涵盖实例化前后的扩展点、自动注入、Aware接口回调以及初始化前后的方法执行。

1714

被折叠的 条评论
为什么被折叠?



