(Spring)IoC循环依赖、jar包类的处理、接口类的处理、多例分析

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

包内类处理:
对于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包内的循环依赖是无解的,因为循环依赖的存在(即相关方法的参数发生了循环关系),所设置的方法参数不全,无法调用,即无法实例化出对象。此时解决方法是抛出一个异常。
故如何查找到某个对象依赖不完全并识别出来是重点:

static BeanMethodDefinition getBeanMethodDefinitionByClassName(String className) {
		if (beanMethodDepandent.isEmpty()) {
			return null;
		}
		for (BeanMethodDefinition beanMethodDefinition : beanMethodDepandent.keySet()) {
			Class<?> klass = beanMethodDefinition.getKlass();
			if (klass.getName().equals(className)) {
				return beanMethodDefinition;
			}
		}
		return null;
	}

在beanMethodDepandent图中,存储了该Bean方法定义及其依赖的参数对应关系,当在pool内查找不到该类的对象,说明该类没有生成,那么就需要获得该类,已知类名称,就可以在图中依据方法定义查找该类,并返回。

接口类(初步实现):
若配置的类是一个接口,而pool中存储的是该接口的实现类:
首先对于接口类,初步的实现我们要做一个约束,就是该接口的实现类只能有一个。
在这个前提下的实现比较简单,在依据接口类名称在pool中查找时,返回应该为null,这个条件和依赖不完全这种情况相同,所以可以同时处理,额外增加一步判断该类是否是接口即可。
当该类是接口,需要遍历对象池,利用:

interfaceClass.isAssignableFrom(klass);

利用该方法可以判断类是否是接口的实现类,再根据查找到的类继续在对象池中查找一次就可以了。
这种查找方式比较简略,只处理单实现类的情况,若思考实际情况就需要额外的配置属性来达到,比如在给接口配置时,应该由用户提供实现类名称,这样就可以查找多个实现类。

接着之前的遗留问题就只剩下多例,对于多例暂时只进行思考:
参考spring,多例要通过给注释中增加scope值进行判断,多例解释:
内存中的每次创建的对象都是一个新的对象,他们的地址值都是不同的,这就是多例模式本质,每获取一个bean 都新生成一个对象提供出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值