服务器之家

服务器之家 > 正文

Spring中@DependsOn注解的作用及实现原理解析

时间:2021-08-23 11:30     来源/作者:brucelwl

本文给大家讲解Spring中@DependsOn注解的作用及实现原理!

官方文档解释

Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean. Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean's initialization.
A depends-on declaration can specify both an initialization-time dependency and, in the case of singleton beans only, a corresponding destruction-time dependency. Dependent beans that define a depends-on relationship with a given bean are destroyed first, prior to the given bean itself being destroyed. Thus, a depends-on declaration can also control shutdown order.
May be used on any class directly or indirectly annotated with org.springframework.stereotype.Component or on methods annotated with Bean.
Using DependsOn at the class level has no effect unless component-scanning is being used. If a DependsOn-annotated class is declared via XML, DependsOn annotation metadata is ignored, and <bean depends-on="..."/> is respected instead.

@DependsOn注解的作用

org.springframework.context.annotation.DependsOn
该注解的属性是一个字符串数组,数组的元素是每个依赖的bean的名称。

  1. @Target({ElementType.TYPE, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface DependsOn {
  5.  
  6. String[] value() default {};
  7.  
  8. }

@DependsOn注解主要用于指定当前bean所依赖的beans。任何被指定依赖的bean都由Spring保证在当前bean之前创建。在少数情况下,bean不是通过属性构造函数参数显式依赖于另一个bean,但却需要要求另一个bean优先完成初始化,则可以使用@DependsOn这个注解。

@DependsOn既可以指定初始化依赖顺序,也可以指定bean相应的销毁执行顺序(仅在单例bean的情况下)。

可用于任何直接或间接带@Component注解的bean或在用@Bean注释的方法上。
如果使用的是xml配置,则需要使用<bean dependens on=“…”/>标签.

简单描述就是@DependsOn可以控制bean的创建、初始化(InitializingBean)、销毁方法执行顺序

示例:假如有三个Bean类叫Aaa、Bbb、Ccc分别实现了如下两个接口。
org.springframework.beans.factory.InitializingBean
org.springframework.beans.factory.DisposableBean

Ccc通过@DependsOn指定依赖bean创建的顺序为Bbb > Aaa

  1. @DependsOn({"bbb","ccc"})
  2. @Service
  3. public class Aaa implements InitializingBean, DisposableBean {
  4. private static final Logger logger = LoggerFactory.getLogger(Aaa.class);
  5.  
  6. public Aaa() {
  7. logger.info(this.getClass().getName() + " Construction");
  8. }
  9.  
  10. @Override
  11. public void afterPropertiesSet() throws Exception {
  12. logger.info(this.getClass().getName() + " afterPropertiesSet");
  13. }
  14.  
  15. @Override
  16. public void destroy() throws Exception {
  17. logger.info(this.getClass().getName() + " destroy");
  18. }
  19. }

Bbb Ccc类实现如下

  1. @Service
  2. public class Bbb implements InitializingBean, DisposableBean {
  3. //实现和Aaa相同
  4. }
  5. @Service
  6. public class Ccc implements InitializingBean, DisposableBean {
  7. //实现和Aaa相同
  8. }

那么初始顺序如下: bbb --> ccc --> aaa

Spring中@DependsOn注解的作用及实现原理解析

而销毁方法执行顺序正好相反如下: aaa --> ccc --> bbb

Spring中@DependsOn注解的作用及实现原理解析

@DependsOn注解的实现原理

Spring在启动时扫描到一个bean,会封装成一个BeanDefinition,如果是AnnotatedBeanDefinition则解析类上的注解信息,发现@DependsOn注解,则读取value值,调用BeanDefinition#setDependsOn保存。
源码见ClassPathBeanDefinitionScanner#doScanAnnotationConfigUtils#processCommonDefinitionAnnotations(AnnotatedBeanDefinition, AnnotatedTypeMetadata)

创建bean时,也就是调用AbstractBeanFactory#doGetBean时,会获取这些被依赖的beanName,按照数组顺序,再调用AbstractBeanFactory#getBean(beanName)来优先创建被依赖的bean,从而达到控制依赖顺序。

除此之外,在创建bean时,还会调用AbstractBeanFactory#registerDisposableBeanIfNecessary来向Spring中注册带有销毁方法的bean,源码见DefaultSingletonBeanRegistry#registerDisposableBean,内部通过LinkedHashMap保存。key为bean名称。进程退出时,会逆序调用销毁方法。
源码见DefaultSingletonBeanRegistry#destroySingletons

  1. public void destroySingletons() {
  2. if (logger.isTraceEnabled()) {
  3. logger.trace("Destroying singletons in " + this);
  4. }
  5. synchronized (this.singletonObjects) {
  6. this.singletonsCurrentlyInDestruction = true;
  7. }
  8.  
  9. String[] disposableBeanNames;
  10. synchronized (this.disposableBeans) {
  11. disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
  12. }
  13. for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
  14. destroySingleton(disposableBeanNames[i]);
  15. }
  16.  
  17. this.containedBeanMap.clear();
  18. this.dependentBeanMap.clear();
  19. this.dependenciesForBeanMap.clear();
  20.  
  21. clearSingletonCache();
  22. }

到此这篇关于Spring中@DependsOn注解的作用及实现原理解析的文章就介绍到这了,更多相关Spring中@DependsOn注解内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/u013202238/article/details/113360497

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部