方法isDependent主要用于检测bean是否存在循环依赖情况。
方便解释将方法registerDependentBean称为YM
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
方便解释将方法isDependent称为XM
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
如:A依赖B,B依赖C,C依赖A(A->B->C->A)
A依赖B
第一步,调用XM,参数为beanName=A,dependentBeanName=B,alreadySeen=null
第二步,检测dependentBeanMap能否获取到A,获取不到,dependentBeans为空,不存在依赖关系。
第三步,调用YM,dependentBeanMap添加key=B,value=A(即为ependentBeans)
B依赖C
第一步,调用XM,参数为beanName=B,dependentBeanName=C,alreadySeen=null
第二步,检测dependentBeanMap能否获取到B,可以获取到,dependentBeans不为空,已存在A
第三步,dependentBeans没有包含C。
第四步,迭代dependentBeans,目前就存在一个A
第五步,alreadySeen添加B
第六步,调用XM,参数为beanName=A,dependentBeanName=C,alreadySeen=有B
第七步,检测dependentBeanMap能否获取到A,获取不到,dependentBeans为空,不存在依赖关系。
第八步,调用YM,dependentBeanMap添加key=C,value=B(即为ependentBeans)
C依赖A
第一步,beanName=C,dependentBeanName=A,alreadySeen=null
第二步,检测dependentBeanMap能否获取到C,可以获取到,dependentBeans不为空,已存在B
第三步,dependentBeans没有包含A。
第四步,alreadySeen添加C
第五步,调用XM,参数为beanName=B,dependentBeanName=A,alreadySeen=有C
第六步,检测dependentBeanMap能否获取到B,可以获取到,dependentBeans不为空,已存在A
第七步,dependentBeans包含A,已检测到存在循环依赖。