其他分享
首页 > 其他分享> > (Spring)IoC循环依赖、jar包类的处理

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

作者:互联网

在上次完成的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