目的:源码调试构造器注入,看看是怎么报错的。
spring:5.2.3
jdk:1.8
首先准备两个循环依赖的类:userService和roleServic
<bean id="userService" class="com.chris.spring.service.UserServiceImpl"> <constructor-arg ref="roleService"/> </bean> <bean id="roleService" class="com.chris.spring.service.RoleService"> <constructor-arg ref="userService"/> </bean>
因为依赖注入的触发点是容器初始化所有非懒加载Bean时候,所以可以直接refresh()方法中的finishBeanFactoryInitialization(beanFactory);方法看起。
1 /** 2 * Finish the initialization of this context‘s bean factory, 3 * initializing all remaining singleton beans. 4 */ 5 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
......
//初始化所有非懒加载的单例bean, 32 // Instantiate all remaining (non-lazy-init) singletons. 33 beanFactory.preInstantiateSingletons(); 34
1.获取BeanDefinition集合

说明:可以看到userService和roleServic已经在容器中,准备初始化了。继续:
2. 判断是否需要实例化

getSingleton(beanName);作用:从缓存中获取单例Bean。
singletonObjects用于缓存单例对象。从singletonObjects获取userService。由于是第一次获取,里面肯定没有。
调用isSingletonCurrentlyInCreation(beanName)方法,判断是不是在初始化中:
singletonsCurrentlyInCreation用于存储正在初始化的Bean。正在初始化的集合里为空,返回false
alreadyCreated用户存放准备好初始化的Bean.
回到原来的方法,又是略过一段代码,判断userService是不是单例bean,肯定是,走这个方法。
检查没问题,userService可以被创建,通过工厂获取对象。从ObjectFactory<?>这个对象工厂中获取bean:singletonFactory.getObject();
问题来了,这个工厂(singletonFactory)哪来的?怎么工作的?
它是传进来的参数,怎么传进来的,再看看调用:
原来是createBean(beanName, mbd, args);返回的。那么就是说明createBean会返回一个工厂对象,这个工厂对象只生产userService这一个对象。
点进createBean方法,找到doCreateBean方法
将BeanDefinition解析成Class,忽略上面这个图停留的地方,继续向下:
判断是构造器注入的,点进去:
这里有两个方法,走第二个,构造器解析:
解析构造器参数,点进去:
解析构造器参数的值,即参数名称:
解析出来是roleService。容器会先将依赖的bean初始化好。然后关联起来。
从这里开始,又是一顿分析roleSerice,过程和userService一样。分析到的结果是:roleSerice依赖userService。又去获取userService:
这个胡汉三又回来了!
然后又是getSingleton(),往下看:
现在准备初始化的bean集合有两个了,而且就有userService,下面看容器时怎么报错的:
又是往下走:到了这里
又检查userService时候可以初始化:
准备初始化的集合里面有userService,报错了!
原文:https://www.cnblogs.com/y13756204582/p/14210894.html