Spring之循环依赖底层源码解析

1.前奏:

AOP的实现:doCreateBean->initializeBean->初始化前、初始化、初始化后applyBeanPostProcessorsAfterInitialization->for (BeanPostProcessor processor : getBeanPostProcessors())遍历执行切面实现的接口,实现AOP

Spring之循环依赖底层源码解析_第1张图片

 

2.循环依赖

@Component
public class AService {
	@Autowired
	private BService bService;

	public void test() {
		System.out.println(bService);
	}
}
@Component
public class BService {
	@Autowired
	private AService aService;

	public void test() {
		System.out.println(aService);
	}
}

Spring之循环依赖底层源码解析_第2张图片

在AService和BService的第一步中:
1.实例化AService->得到一个对象->zhouyuMap
2.2.2 填充BService属性->去单例池中找BService->zhouyuMap->BService对象
...

2.1 实例化BService->得到一个对象->zhouyuMap
2.2 填充AService属性->去单例池中找AService->zhouyuMap->AService对象
...这样BService就正常创建完成

 注意:

1.这个时候,BService中属性是没有值的,但是后面因为一直操作的都是AService对象,后面会解决AService属性值的问题,这样也就解决了BService属性值的问题

2.但是如果AService有AOP操作,这样就会引入问题,因为zhouyuMap里面一直存放的是代理之前的对象

 3.@Async注解是在beanPostProcess之后,所以AOP生成代理对象后,此注解会重新生成代理对象:这这样exponsedObject != bean,就会抛出异常,这样为啥要抛异常呢?=》因为第二张图,第6点放入单例池中的对象是@Async的代理对象,这样和之前属性注入的AOP代理对象不一致,所以需要抛出异常。所以在使用@Asyn的时候,需要在依赖注入的地方加入@Lazy注解

Spring之循环依赖底层源码解析_第3张图片

Spring之循环依赖底层源码解析_第4张图片

 4.如果AService和BService都是原型Bean,那么循环依赖无法解决。因为三级缓存只有单例Bean的存储,针对原型的没有存储

5.@Transaction注解的添加,不像@Async一样,添加一个BeanPostProcess在第6步的时候代理生成一个AOP对象。所以不会出现问题

你可能感兴趣的:(java,spring)