作用
@DependsOn注解可以定义在类和方法上,意思是我这个组件要依赖于另一个组件,也就是说被依赖的组件会比该组件先注册到IOC容器中。
在哪里被解析
解析的地方在 ComponentScanAnnotationParser类#doScan方法 【可查看
Spring基于注解的扫描底层流程】
代码为 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
将元数据的信息塞入到 BeanDefinition里面
在哪里别调用
调用的地方在 AbstractBeanFactory类#doGetBean方法里面 ,代码展示
//根据获取BeanDefinition信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//校验一下正确性
checkMergedBeanDefinition(mbd, beanName, args);
// 拿出DependsOn注解的信息
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检测beanName是不是被dep依赖了,如果是则出现循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
汇总说明
这种本质上也是循环依赖问题产生的一种,而且Spring没有办法解决,唯有靠写代码的时候进行避免。
也就是说 dependentBeanMap 里面存储了一样的依赖的时候就会抛出错误。