Spring中@DependsOn注解的作用及实现原理解析
本文给大家讲解Spring中@DependsOn注解的作用及实现原理!
官方文档解释
Beansonwhichthecurrentbeandepends.Anybeansspecifiedareguaranteedtobecreatedbythecontainerbeforethisbean.Usedinfrequentlyincaseswhereabeandoesnotexplicitlydependonanotherthroughpropertiesorconstructorarguments,butratherdependsonthesideeffectsofanotherbean'sinitialization.
Adepends-ondeclarationcanspecifybothaninitialization-timedependencyand,inthecaseofsingletonbeansonly,acorrespondingdestruction-timedependency.Dependentbeansthatdefineadepends-onrelationshipwithagivenbeanaredestroyedfirst,priortothegivenbeanitselfbeingdestroyed.Thus,adepends-ondeclarationcanalsocontrolshutdownorder.
Maybeusedonanyclassdirectlyorindirectlyannotatedwithorg.springframework.stereotype.ComponentoronmethodsannotatedwithBean.
UsingDependsOnattheclasslevelhasnoeffectunlesscomponent-scanningisbeingused.IfaDependsOn-annotatedclassisdeclaredviaXML,DependsOnannotationmetadataisignored,andisrespectedinstead.
@DependsOn注解的作用
org.springframework.context.annotation.DependsOn
该注解的属性是一个字符串数组,数组的元素是每个依赖的bean的名称。
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public@interfaceDependsOn{
String[]value()default{};
}
@DependsOn注解主要用于指定当前bean所依赖的beans。任何被指定依赖的bean都由Spring保证在当前bean之前创建。在少数情况下,bean不是通过属性或构造函数参数显式依赖于另一个bean,但却需要要求另一个bean优先完成初始化,则可以使用@DependsOn这个注解。
@DependsOn既可以指定初始化依赖顺序,也可以指定bean相应的销毁执行顺序(仅在单例bean的情况下)。
可用于任何直接或间接带@Component注解的bean或在用@Bean注释的方法上。
如果使用的是xml配置,则需要使用
简单描述就是@DependsOn可以控制bean的创建、初始化(InitializingBean)、销毁方法执行顺序。
示例:假如有三个Bean类叫Aaa、Bbb、Ccc分别实现了如下两个接口。
org.springframework.beans.factory.InitializingBean
org.springframework.beans.factory.DisposableBean
Ccc通过@DependsOn指定依赖bean创建的顺序为Bbb>Aaa
@DependsOn({"bbb","ccc"})
@Service
publicclassAaaimplementsInitializingBean,DisposableBean{
privatestaticfinalLoggerlogger=LoggerFactory.getLogger(Aaa.class);
publicAaa(){
logger.info(this.getClass().getName()+"Construction");
}
@Override
publicvoidafterPropertiesSet()throwsException{
logger.info(this.getClass().getName()+"afterPropertiesSet");
}
@Override
publicvoiddestroy()throwsException{
logger.info(this.getClass().getName()+"destroy");
}
}
BbbCcc类实现如下
@Service
publicclassBbbimplementsInitializingBean,DisposableBean{
//实现和Aaa相同
}
@Service
publicclassCccimplementsInitializingBean,DisposableBean{
//实现和Aaa相同
}
那么初始顺序如下:bbb-->ccc-->aaa
而销毁方法执行顺序正好相反如下:aaa-->ccc-->bbb
@DependsOn注解的实现原理
Spring在启动时扫描到一个bean,会封装成一个BeanDefinition,如果是AnnotatedBeanDefinition则解析类上的注解信息,发现@DependsOn注解,则读取value值,调用BeanDefinition#setDependsOn保存。
源码见ClassPathBeanDefinitionScanner#doScan,AnnotationConfigUtils#processCommonDefinitionAnnotations(AnnotatedBeanDefinition,AnnotatedTypeMetadata)
创建bean时,也就是调用AbstractBeanFactory#doGetBean时,会获取这些被依赖的beanName,按照数组顺序,再调用AbstractBeanFactory#getBean(beanName)来优先创建被依赖的bean,从而达到控制依赖顺序。
除此之外,在创建bean时,还会调用AbstractBeanFactory#registerDisposableBeanIfNecessary来向Spring中注册带有销毁方法的bean,源码见DefaultSingletonBeanRegistry#registerDisposableBean,内部通过LinkedHashMap保存。key为bean名称。进程退出时,会逆序调用销毁方法。
源码见DefaultSingletonBeanRegistry#destroySingletons
publicvoiddestroySingletons(){
if(logger.isTraceEnabled()){
logger.trace("Destroyingsingletonsin"+this);
}
synchronized(this.singletonObjects){
this.singletonsCurrentlyInDestruction=true;
}
String[]disposableBeanNames;
synchronized(this.disposableBeans){
disposableBeanNames=StringUtils.toStringArray(this.disposableBeans.keySet());
}
for(inti=disposableBeanNames.length-1;i>=0;i--){
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();
}
到此这篇关于Spring中@DependsOn注解的作用及实现原理解析的文章就介绍到这了,更多相关Spring中@DependsOn注解内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。