可能是最卷的Spring源码系列(十二):循环依赖

看过太多关于讲循环依赖的文章,感觉大部分都只讲到了循环依赖是怎么实现的,暂时还没有看到有文章能真正讲明白为什么要使用三级缓存,为了能更好的分析spring接下的代码,所以这篇就率先被安排了。

缓存级别的定义

在分析spring注解之前我们先要达成一个共识,就是对三个级别缓存的定义,所以本篇文章中对三个级别的缓存有如下定义:

//  一级缓存  单例池
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存 早期单例池
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存  单例工厂池
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

一级缓存是用来存最终的结果的,通常大家对一级缓存是没有什么异议的,关键是在二级和三级缓存上。
为什么我要把二三级这么定义,这存粹是根据缓存创建的顺序来定义的,根据通常的缓存定义,最早会进入低级别缓存,之后依次进入高级别缓存。
那为什么有人把早期单例池定义为三级缓存,首先要说明的是这么定义是完全没有问题的,这样定义考虑的是缓存的作用,我们知道一旦进入了高级别的缓存之后(在没有更新的情况下)就不需要在去低级别中的缓存去取了
,但是当bean进入earlySingletonObjects 还是会去singletonFactories 里面去取?至于为什么,我们后面会讲到。
所以我们不要纠结二三级缓存怎么定义的,在我看来这两种定义方式都是正确的,但是都不是完全准确的,看完这篇文章,你就会知道我为什么这么说。

循环依赖

进入正题,先明确几个问题
1.想实现循环依赖最少需要哪种类型的缓存?
先说答案:两个级别的级缓存就够了,一级缓存和二级缓存就可以完成
2.如果想实现循环依赖+aop最少需要哪几个级别的缓存?
答案同上:两个级别的级缓存就够了,一级缓存和二级缓存就可以完成
(这个时候肯定会有朋友说我吹牛逼了,因为大部分的文章和视频都在讲三级缓存的作用是实现AOP,所以要搞清aop和三级缓存的关系,spring的确是通过三级缓存实现aop的,但是想实现aop不一定要使用三级缓存)
3.为什么spring使用三级缓存实现aop?
让aop过程推迟
4.使用三级缓存后,假如去掉二级缓存,一级缓存+三级缓存可以实现循环依赖+aop延迟吗?
可以
5.接上一个问题,那spring为什么还要使用二级缓存
为了一点点的性能

所以总结一下就是:
1.如果只想实现循环依赖,一级+二级缓存就够了。
2.如果想实现循环依赖+aop,一级缓存+二级缓存也可以完成。
3.如果想实现循环依赖+aop+aop过程推迟,一级缓存+三级缓存就可以完成,引入三级缓存时会牺牲一定的性能
4.如果想实现循环依赖+aop+aop过程推迟+性能优化,需要一级缓存+二级缓存+三级缓存
接下来我会通过模拟spring的过程来实现上述需求,之后再分析spring的源码

两个级别缓存实现循环依赖(一级+二级)

下面我会写一个例子证明一级+二级缓存可以完成循环依赖,并且我也有尝试过把spring中的三级缓存删掉,二级缓存 把工厂改成早期单例,完全可以实现循环依赖,如果你对下面的例子不认同可以私信我要我改造的代码。
两个循环依赖的类:
在这里插入图片描述
在这里插入图片描述
基于一级+二级缓存手写循环依赖:

public class SimpleContent {
	// 一级缓存
	static Map<String,Object> m1 = new HashMap<>();
	// 二级缓存
	static Map<String,Object> m2 = new HashMap<>();
	public static void main(String[] args) throws Exception {
		// 创建dx
		DX dx = create(DX.class);
		DY dy = create(DY.class);
		System.out.println();
	}
	public static <T> T create(Class<T> beanClass) throws Exception {
		// 如果一级缓存存在 直接返回
		String beanName = beanClass.getSimpleName().toLowerCase();
		Object cache = m1.get(beanName);
		if (cache != null) {
			return (T)cache;
		}
		T bean = beanClass.newInstance();
		// 加入到二级缓存
		m2.put(beanName, bean);
		injection(bean);
		// 删除二级缓存
		m2.remove(beanName, bean);
		m1.put(beanName, bean);
		return bean;
	}
	public static void injection(Object bean) throws Exception {
		Class<?> aClass = bean.getClass();
		Field[] fields = aClass.getDeclaredFields();
		for (Field field : fields) {
			String fieldName = field.getName();
			String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			String fieldClass = field.getType().getName();
			Class<?> aClass1 = Class.forName(fieldClass);
			Object cache = m1.get(field.getName());
			if (cache == null) {
				cache = m2.get(field.getName());
				if (cache == null) {
					cache = create(aClass1);
				}
			}
			Method method = aClass.getMethod(methodName, aClass1);
			method.invoke(bean, cache);
		}
	}
}

可以证明问题一,一级+三级缓存即可实现循环依赖

一级+二级缓存实现AOP

如果想在上面的代码中实现AOP也非常简单

public class AopContent {
	// 一级缓存
	static Map<String,Object> m1 = new HashMap<>();
	// 二级缓存
	static Map<String,Object> m2 = new HashMap<>();
	public static void main(String[] args) throws Exception {
		// 创建dx
		AopContent aopContent = new AopContent();
		DX dx = aopContent.create(DX.class);
		DY dy = aopContent.create(DY.class);
		dy.getDx().getDy().getDx().print();
	}
	public <T> T create(Class<T> beanClass) throws Exception {
		// 如果一级缓存存在 直接返回
		String beanName = beanClass.getSimpleName().toLowerCase();
		Object cache = m1.get(beanName);
		if (cache != null) {
			return (T)cache;
		}
		T bean = beanClass.newInstance();
		// 执行aop之后进缓存
		bean = (T) aop(bean);
		// 加入到二级缓存
		m2.put(beanName, bean);
		injection(bean);
		// 删除二级缓存
		m2.remove(beanName, bean);
		m1.put(beanName, bean);
		return bean;
	}
	public <T> void injection(T bean) throws Exception {
		Class<?> clazz = bean.getClass().getSuperclass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			Autowired annotationsByType = field.getAnnotation(Autowired.class);
			if (annotationsByType == null) {
				continue;
			}
			String fieldName = field.getName();
			String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			String fieldClass = field.getType().getName();
			Class<?> aClass1 = Class.forName(fieldClass);
			Object cache = m1.get(field.getName());
			if (cache == null) {
				cache = m2.get(field.getName());
				if (cache == null) {
					cache = create(aClass1);
				}
			}
			Method method = clazz.getMethod(methodName, aClass1);
			method.invoke(bean, cache);
		}
	}
	public Object aop(Object bean) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(bean.getClass());
		enhancer.setCallback(new MyMethodInterceptor(bean));
		Object proxyObj = enhancer.create();
		// 返回代理对象
		return proxyObj;
	}
	class MyMethodInterceptor implements MethodInterceptor {
		Object obj;

		public MyMethodInterceptor(Object obj) {
			this.obj = obj;
		}

		@Override
		public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
			if ("print".equals(method.getName())) {
				System.out.println("aop after");
			}
			Object invoke = method.invoke(obj, objects);
			if ("print".equals(method.getName())) {
				System.out.println("aop before");
			}
			return invoke;
		}
	}
}

一级+三级缓存实现AOP延迟

public class StandardContent {
	// 一级缓存
	static Map<String,Object> m1 = new HashMap<>();
	// 三级缓存
	static Map<String, ObjectFactory<Object>> m3 = new HashMap<>();
	public static void main(String[] args) throws Exception {
		// 创建dx
		StandardContent content = new StandardContent();
		DX dx = content.create(DX.class);
		DY dy = content.create(DY.class);
		System.out.println(dx.getDy().getDx() == dy.getDx());
		dy.getDx().getDy().getDx().print();
	}
	public <T> T create(Class<T> beanClass) throws Exception {
		// 如果一级缓存存在 直接返回
		String beanName = beanClass.getSimpleName().toLowerCase();
		Object cache = getSingleton(beanName);
		if (cache != null) {
			return (T)cache;
		}
		T bean = beanClass.newInstance();
		// 加入到三级缓存
		m3.put(beanName, ()->{
			return aop(bean);
		});
		T exposedObject = bean;
		injection(bean);
		Object earlySingletonReference = getSingleton(beanName);
		if (exposedObject == bean) {
			exposedObject = (T) earlySingletonReference;
		}
		else {
			// 如果被别的bean依赖则报错

		}
		// 三级缓存
		if (m3.containsKey(beanName)) {
			m3.remove(beanName);
		}
		// 进入一级缓存
		m1.put(beanName, bean);
		return exposedObject;
	}
	public <T> void injection(T bean) throws Exception {
		Class<?> clazz = bean.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			Autowired annotationsByType = field.getAnnotation(Autowired.class);
			if (annotationsByType == null) {
				continue;
			}
			String fieldName = field.getName();
			String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			String fieldClass = field.getType().getName();
			Class<?> aClass1 = Class.forName(fieldClass);
			Object cache = getSingleton(field.getName());
			if (cache == null) {
				cache = create(aClass1);
			}
			Method method = clazz.getMethod(methodName, aClass1);
			method.invoke(bean, cache);
		}
	}
	public Object aop(Object bean) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(bean.getClass());
		enhancer.setCallback(new MyMethodInterceptor(bean));
		Object proxyObj = enhancer.create();
		// 返回代理对象
		return proxyObj;
	}
	class MyMethodInterceptor implements MethodInterceptor {
		Object obj;

		public MyMethodInterceptor(Object obj) {
			this.obj = obj;
		}

		@Override
		public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
			if ("print".equals(method.getName())) {
				System.out.println("aop after");
			}
			Object invoke = method.invoke(obj, objects);
			if ("print".equals(method.getName())) {
				System.out.println("aop before");
			}
			return invoke;
		}
	}
	public Object getSingleton(String beanName) {
		Object bean = m1.get(beanName);
		if (bean != null) {
			return bean;
		}
		ObjectFactory<Object> objectObjectFactory = m3.get(beanName);
		if (objectObjectFactory != null) {
			bean = objectObjectFactory.getObject();
			return bean;
		}
		return null;
	}
}

一级+二级+三级缓存实现aop+性能优化

public class EnhancerContent {
	// 一级缓存
	static Map<String,Object> m1 = new HashMap<>();
	// 二级缓存
	static Map<String,Object> m2 = new HashMap<>();
	// 三级缓存
	static Map<String, ObjectFactory<Object>> m3 = new HashMap<>();
	public static void main(String[] args) throws Exception {
		// 创建dx
		EnhancerContent content = new EnhancerContent();
		DX dx = content.create(DX.class);
		DY dy = content.create(DY.class);
		System.out.println(dx.getDy().getDx() == dy.getDx());
		dy.getDx().getDy().getDx().print();
	}
	public <T> T create(Class<T> beanClass) throws Exception {
		// 如果一级缓存存在 直接返回
		String beanName = beanClass.getSimpleName().toLowerCase();
		Object cache = getSingleton(beanName);
		if (cache != null) {
			return (T)cache;
		}
		T bean = beanClass.newInstance();
		// 加入到三级缓存
		m3.put(beanName, ()->{
			return aop(bean);
		});
		T exposedObject = bean;
		injection(bean);
		exposedObject = initializeBean(bean);
		Object earlySingletonReference = getSingleton(beanName);;
		if (exposedObject == bean) {
			exposedObject = (T) earlySingletonReference;
		}
		else {
			// 如果被别的bean依赖则报错

		}
		// 删除二级缓存和三级缓存
		if (m2.containsKey(beanName)) {
			m2.remove(beanName);
		}
		if (m3.containsKey(beanName)) {
			m3.remove(beanName);
		}
		// 进入一级缓存
		m1.put(beanName, bean);
		return exposedObject;
	}
	public <T> void injection(T bean) throws Exception {
		Class<?> clazz = bean.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			Autowired annotationsByType = field.getAnnotation(Autowired.class);
			if (annotationsByType == null) {
				continue;
			}
			String fieldName = field.getName();
			String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			String fieldClass = field.getType().getName();
			Class<?> aClass1 = Class.forName(fieldClass);
			Object cache = getSingleton(field.getName());
			if (cache == null) {
				cache = create(aClass1);
			}
			Method method = clazz.getMethod(methodName, aClass1);
			method.invoke(bean, cache);
		}
	}

	/**
	 * 模拟bean初始化流程
	 * @param bean
	 * @param <T>
	 * @return
	 */
	public <T> T initializeBean(T bean) {
		//这个过程中可能被修改或者代理
		return bean;
	}
	public Object aop(Object bean) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(bean.getClass());
		enhancer.setCallback(new MyMethodInterceptor(bean));
		Object proxyObj = enhancer.create();
		// 返回代理对象
		return proxyObj;
	}
	class MyMethodInterceptor implements MethodInterceptor {
		Object obj;

		public MyMethodInterceptor(Object obj) {
			this.obj = obj;
		}

		@Override
		public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
			if ("print".equals(method.getName())) {
				System.out.println("aop after");
			}
			Object invoke = method.invoke(obj, objects);
			if ("print".equals(method.getName())) {
				System.out.println("aop before");
			}
			return invoke;
		}
	}
	public Object getSingleton(String beanName) {
		Object bean = m1.get(beanName);
		if (bean != null) {
			return bean;
		}
		bean = m2.get(beanName);
		if (bean != null) {
			return bean;
		}
		ObjectFactory<Object> objectObjectFactory = m3.get(beanName);
		if (objectObjectFactory != null) {
			bean = objectObjectFactory.getObject();
			m3.remove(beanName);
			m2.put(beanName, bean);
			return bean;
		}
		return null;
	}
}

相信这篇文章已经为你解答了很多对循环依赖的疑惑,下一篇我们会对spring中的实现详细分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值