ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

(Spring)IoC循环依赖、jar包类的处理

2021-04-11 23:31:00  阅读:175  来源: 互联网

标签:Map 依赖 包内 Spring jar bean Bean 包类 方法


在上次完成的IoC中,使用的BeanDefinition中有一个值用于判断是否注入完成,当我们遇到循环依赖时,代码会持续循环执行,原因是处理不到该判断值变化的部分,那么当我们把值变换提前,开始注入就进行更改,那么循环依赖就处理好了。

private static void doInject(BeanDefinition bean) throws Exception {
		if (bean.isInject()) {
			return;
		}
		bean.setInject(true);

		Object object = bean.getObject();
		Class<?> klass = bean.getKlass();
		Field[] fields = klass.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAnnotationPresent(Autowired.class)) {
				continue;
			}
			Autowired autowired = field.getAnnotation(Autowired.class);
			String value = autowired.value();
			
			Object property = null;
			Class<?> fieldType = field.getType();
			String typeName = fieldType.getName();
			if (value.length() <= 0) {
				property = getBean(typeName);
			} else {
				String valueString = autowired.value();
				property = TypeParser.getValue(typeName, valueString);
			}
			
			String fieldName = field.getName();
			String setterName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			Method setterMethod = klass.getDeclaredMethod(setterName,
					new Class<?>[] {fieldType});
			setterMethod.invoke(object, property);
		}
	}

对于Jar包内的类,采取由用户书写一个函数来实例化,但是由IoC调用的方法。即在本身包中新建一个类用于配置,其中书写的方法由新增的Bean注解标记,扫描到该方法,由IoC调用,即可将Jar包内的类实例出来。
对该方法应该如下理解:
1.方法的返回值是一个BeanDefinition,方便与放入pool
2.在方法中实例化相关类,这是主要目的
3.允许方法的参数是其他Bean,这点是处理难点,当所需的Bean未生成甚至该类在其他包内需要额外处理

此时重点问题是依赖存在于参数,那么如何判断依赖是否满足及当满足时运行该方法。

这种主要的应用场景是需要的Bean存在于其他Jar包内,无法获取该参数,即依赖此时无法完成,应利用Map先存储。
额外新建一个定义类BeanMethod,用于被Bean标记得方法,对应类的实例化对象,需要注入数目(即参数类型个数)

总共生成两个Map,一个List
第一个Map:用于存储方法BeanMethod和该类所需参数类型(使用Map存储,虽然值没有用处,但是借助Map键只能出现一次的特性可以解决参数重复出现的情况)的对应关系。

private static final Map<BeanMethodDefinition, Map<Class<?>, Integer>> beanMethodDepandent;

List:用于存储依赖关系以满足(即BeanMethod中的注入数目为0)的方法

private static final List<BeanMethodDefinition> allreadyBeanMethodPool;

第二个Map:该Map主要是为了效率考虑,我们每生成一个Bean,会生成其自己所需的依赖关系,那么依赖于这个Bean的方法,我们应该进行相应的处理,利用存储了该Bean及依赖于该Bean的BeanMethodDefinition列表,可以简化寻找的过程,按键找到对应的值,进行注入数目减一

private static final Map<Class<?>, List<BeanMethodDefinition>> beanClassPool;

jar包内的循环依赖是无解的,因为循环依赖的存在(即相关方法的参数发生了循环关系),所设置的方法参数不全,无法调用,即无法实例化出对象。此时解决方法是抛出一个异常,判断条件是该bean方法不为空(此点的因素是方法执行过后生成的带对象bean,会将方法设置为null)

标签:Map,依赖,包内,Spring,jar,bean,Bean,包类,方法
来源: https://blog.csdn.net/MagicSound/article/details/115606177

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有