先获取,没有的话再创建,如下图所示
创建bean的主要流程如下:
依赖是在目标对象里,代理对象的字段没有值,如下图所示:
Spring在解决循环依赖时使用了 三级缓存,如果没有代理的话,用一级缓存就可以解决。二三级缓存主要是为了解决代理的生成。
一级缓存(也叫单例池): singletonObjects,存放已经经历了完整生命周期的Bean对象。
二级缓存: earlySingletonObjects,存放早期暴露出来的Bean对象,Bean的生命周期未结束(属性还未填充完整),存放半成品的Bean。
三级缓存: singletonFactories,存放可以生成Bean的工厂,主要是解决aop特性,()->getEarlyBeanReference(beanName,mbd,bean),getEarlyBeanReference()返回增强后的bean。
在代码中创建3个Bean,然后相互依赖,再创建切面,让这几个Bean生成代理。
@Component
public class TestA {
@Autowired
TestB testB;
public void test(){
System.out.println("----aaa----");
}
}
@Component
public class TestB {
@Autowired
TestC testC;
public void test(){
System.out.println("----bbb----");
}
}
@Component
public class TestC {
@Autowired
TestA testA;
public void test(){
System.out.println("----ccc----");
}
}
@Aspect
@Configuration
public class TestAspect {
@Pointcut("execution(* com.shopping.demo24.component.*.test(..))")
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(this.getClass().getSimpleName()+"-around:before");
Object result=joinPoint.proceed();
System.out.println(this.getClass().getSimpleName()+"-around:after");
return result;
}
}
1. 获取a->创建a->将a添加到singletonFactories->设置依赖b->获取b
2. 创建b->将b添加到singletonFactories->设置依赖c开始->获取c
3.创建c->将c添加到singletonFactories
此时缓存池中的 bean 如下,没有写的为空
singletonFactories:a, b, c
4. 给c设置依赖a开始->获取a
先从singletonObjects中获取,没有,再从earlySingletonObjects中获取,也没有,最后在singletonFactories的ObjectFactory中获取。获取以后添加到earlySingletonObjects中,这里面的a是增强后的a,但是依赖的属性没有设置。再从singletonFactories中删除
此时
earlySingletonObjects: a
singletonFactories: b,c
ObjectFactory的值为 () -> getEarlyBeanReference(beanName, mbd, bean)
从ObjectFactory获取时会对a调用BeanPostProcessor的getEarlyBeanReference()返回增强后的a
包装对象,生成代理
a 在这里增强后,在后面的postProcessAfterInitialization()方法中,创建代理对象(增强对象)的AbstractAutoProxyCreator中如果有对应的earlyProxyReferences记录(这里的记录不是增强对象,而是原始对象),就不会再被增强。
5. 通过反射,给c设置依赖
给c设置依赖a结束,调用initializeBean()方法,生成代理对象,创建完c,将c添加到singletonObjects中,删除earlySingletonObjects和singletonFactories中的对应值。
此时
earlySingletonObjects:a
singletonFactories: b
singletonObjects: c
6: 给b设置依赖c结束,调用initializeBean()方法,生成代理对象, 创建完b,将b添加到singletonObjects中b是代理对象
earlySingletonObjects:a
singletonFactories: null
singletonObjects: b,c
7: 给a设置依赖b完成
此时,对于 a, 调用initializeBean()方法返回的不是增强对象,
因为earlyProxyReferences中存在a,表示它已经被增强过
获取earlySingletonObjects中的a,这里的a是增强对象。
创建完a,将a添加到singletonObjects中
earlySingletonObjects:null
singletonFactories: null
singletonObjects: b,c,a
至此,a,b,c 三个bean创建完成,也都加到了 singletonObjects 中,其他两个缓存池都为空。