Spring依赖注册
假设有ClassA和ClassC,ClassA依赖于ClassC
@Component
@DependsOn("c")
public class A {
@Autowired
private B b;
}
@Component
public class C {
}
Spring注册依赖关系
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry
...
/** Map between dependent bean names: bean name --> Set of dependent bean names
IOC容器创建完成后:{c=[a]}
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies
IOC容器创建完成后:{a=[c]}
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* @param beanName the name of the bean
* @param dependentBeanName the name of the dependent bean
*实际运行过程中: beanName -->c, dependentBeanName-->a
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding
// synchronization...
// 1.解析别名
String canonicalName = canonicalName(beanName);
// 2.拿到依赖canonicalName的beanName集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
// 3.如果dependentBeans包含dependentBeanName,则表示依赖关系已经存在,直接返回
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// No entry yet -> fully synchronized manipulation of the dependentBeans
// Set
// 4.如果依赖关系还没有注册,则将两者的关系注册到dependentBeanMap和dependenciesForBeanMap缓存
synchronized (this.dependentBeanMap) {
// 4.1 将dependentBeanName添加到依赖canonicalName的beanName集合中
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
// 4.2 将canonicalName添加到dependentBeanName依赖的beanName集合中
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
}