spring源码解读(三)bean生命周期
1 目的分析this.finishBeanFactoryInitialization(beanFactory); 方法,熟悉里面扩展点等。
2 为添加spring-aop我们对01-spring-ioc中的类进行补充,添加切面类(放在可以被被扫描的地方),并在App上添加@EnableAspectJAutoProxy 注解
@Component
@Aspect
public class MyAspectj {
@Before("execution(* com.meituan.service.*.test(..))")
public void before() {
System.out.println("before--------------------------");
}
}
//为AService添加注入
@Component
@Scope(proxyMode = ScopedProxyMode.NO)
public class AService {
@Autowired
private BService bService;
public void test() {
System.out.println("I am AService");
}
}
@EnableAspectJAutoProxy 注解会将AspectJAutoProxyRegistrar导入,其实现了ImportBeanDefinitionRegistrar接口,会执行registerBeanDefinitions方法将org.springframework.aop.config.internalAutoProxyCreator 注入到容器
这里是在前面的refresh方法中的注入beanPostProcessor将bean后置处理器注入容器的(会将bd中实现了beanPostProcessor接口的bd实列化出来加入到bean后置处理器容器中)
3 进入protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) 方法
执行到这里,传入的是lamda表达式,存储在beanFactory的embeddedValueResolvers集合里
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
//符合函数式接口,strVal形参在实际调用的时候传入
进入preInstantiateSingletons()方法,我们暂时不讨论FactoryBean相关,按照一般bean查看初始化过程
在getbean这里我们在断点上设置beanName=AService,点击进这个方法,一层一层点击进去,到doGetBean方法
注意: 这里有一个this.getSingleton(beanName),这是第一去拿bean,点击进去到getSingleton方法中
可以看到这里先从单列池从去拿,很明显我们第一次过来拿到null,
然后判断是否是正确创建的bean,也不是所以直接返回null,这是我们第一次去拿bean,拿到null,单列池和和正在创建的bean集合都没有。
返回到doGetBean进行执行
这里会将当前bean的名字(字符串)设置进alreadyCreated集合中
然后判断是否有dependOn注解,有的话先去实列化别的,我们这里没有直接跳过
进入到单列创建
调用getSingleton,传入的是lamda表达式点进去看。
里面会有Object singletonObject = this.singletonObjects.get(beanName); 第二次直接去单列池拿,还是空
继续执行下面逻辑this.beforeSingletonCreation(beanName);这里会将当前beanname存入singletonsCurrentlyInCreation(单列正在创建)
singletonObject = singletonFactory.getObject(); 调用传入的lamda表达式执行,this.createBean(beanName, mbd, args);
进入createBean后,到断点处,进入此方法,这里会拿到所有的beanPostProcessor,调用里面实现了InstantiationAwareBeanPostProcessor接口的beanPostProcessor的InstantiationAwareBeanPostProcessor方法
1 这里是第一次调用bean后置处理器,当反悔的beanInstance不为空的时候就不会走bean的正常初始化流程,并且会调用postProcessAfterInitialization,并返回bean,可以自己实现InstantiationAwareBeanPostProcessor,返回自己设置的bean
第一个扩展点
继续执行,上一步拿到的是null,所以这里开始bean的创建了,进入断点方法
进入断点方法,开始创建bean,第2次调用后置处理器,决定以哪种方式创建bean对象,(先通过工厂创建;如果不能,使用构造方法;最后使用无参构造 )假如类中有多个构造方法,生效的优先级(@Autowired > autowireMode =3 > 无参构造)、
第二次扩展点
执行到这一步,开始构造器推测,也是通过执行BeanPostProcessor来的
点进方法,判断的是SmartInstantiationAwareBeanPostProcessor接口,执行determineCandidateConstructors方法,我们一个一个找,发现调用的是AutowiredAnnotationBeanPostProcessor类(他实现了SmartInstantiationAwareBeanPostProcessor接口)
返回到protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException 方法
我们实列化出来的对象通过包装类已经拿到了,有一个缓存操作,对于非单列的bean下次进来就可以不用执行构造器推测等操作,
3 第三次执行Bean后置处理器,允许后置处理器修改合并的bean定义 ,实现类 AutowiredAnnotationBeanPostProcessor,用于扫描 @Autowired和@Value修饰的属性和方法,封装到InjectionMetadata。
AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。会调用到AutowiredAnnotationBeanPostProcessor 的buildAutowiringMetadata()方法,buildAutowiringMetadata方法解析等待自动注入类的所有属性。它通过分析所有字段和方法并初始化org.springframework.beans.factory.annotation.InjectionMetadata类的实例来实现。
继续执行
第4次调用后置处理器 提前暴露对象的引用到 singletonFactory 单例工厂中,解决循环引用的问题,提前将工厂对象放入缓存中
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
这一行体现支持循环依赖,我们可以通过设置allowCircularReferences来不开启循环依赖
里面内容如下,添加进容器中
继续执行
第5次,第6次调用后置处理器 注入依赖
我们点进this.populateBean(beanName, mbd, instanceWrapper);方法看看(这里有spring调用第五次和第六次后置处理器)
这里是第五次调用bean后置处理器,在目标对象实例化之后调用,此时对象被实例化,但是对象的属性还未设置。如果该方法返回
fasle,则会忽略之后的属性设置。返回true,按正常流程设置属性值
继续向下,到第六次执行后置处理器
if (continueWithPropertyPopulation) { //第五次bean后置处理器调用返回false就不执行了
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) { //判断属性注入方式是否是by_name或者是by_type,这里是0默认注入方式,需要程序员手动注入,即添加Autowired注解
//才会注入,现在注解方式获取的bd里面的autowiredMode都是0,
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
//第六次调用后置处理器,可以在该方法内对属性值进行修改(此时属性值还未设置,但可以修改原本会设置的进去的属性值)。
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//处理 @Autowired 属性注入逻辑
// AutowiredAnnotationBeanPostProcessor.postProcessProperties
//InjectionMetadata#inject
//AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
//DefaultListableBeanFactory#resolveDependency
//DefaultListableBeanFactory#doResolveDependency
//DependencyDescriptor#resolveCandidate //此方法直接返回 beanFactory.getBean(beanName);
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
//普通数据注入
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
第6次调用后置处理器,用来处理Bean中 属性注入,包括 @Autowired 注入;此时如果存在循环引用的问题,也会一并处理掉(从单例工厂中获取属性bean,生成earlySingletonObject,添加到earlySingletonObjects中,解决循环依赖问题)
即Aservice需要注入Bservice,但是Bservice还没有初始化出来,这时候会去初始化Bservice,到需要注入Aservice的,能从单列工厂中拿到Aservice,,然后继续执行完剩下流程,调用返回,继续执行AService的后置处理,解决循环依赖
接下来进入第七次bean后置处理器和第八次后置处理器(spring aop基于第八次后置处理器的执行)
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
//如果实现了aware借口会,向里面注入对应的属性
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic())
// 第七次执行后置处理器,主要与aware借口注入属性
// 如果配置了@PostConstruct 会调用
// InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
//第八次执行bean后置处理器,
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
构造方法 > @Autowired (属性注入)> @PostContruct
8 接下来执行第八次bean后置处理器,这里会通过代理模式返回aop加强后的bean,默认是cglib
9 第九次执行后置处理器,标记单例bean为可销毁的,