Spring注解@DependsOn解析

作者:刘牌 时间:2022-01-11 08:20:35 

介绍

今天要分享得是Spring的@DependsOn注解,对于@DependsOn,我们从它的名称里面就能看出意思是“依赖于”,那么在Spring中,它的作用就是解决Bean的创建依赖,比如某个Bean在创建的时候依赖另外一个bean,所以需要另外一个bean先创建,然后再创建自己。

注解详情

@DependsOn注解可以标注在类上和方法上面,只有一个属性value,它是一个数组,表示依赖的bean名称的数组,可以指定一个或者多个。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {

String[] value() default {};

使用

如下,在DependsOnBeanA上标注了@DependsOn注解,那么DependsOnBeanA需要在Bean dependsOnBeanB创建完成之后才能创建自己,这里value的值为bean的名称,如果没有对bean设置名称,那么就为首字母为小写的类名。

@Component
@DependsOn(value = {"dependsOnBeanB"})
public class DependsOnBeanA {

}

源码解析

spring扫描到所有的标有@Component(@Service,@Repository等注解本质就是@Component)的类和标有@Bean的方法后,会进行处理,这里,它会判断是否标注有@DependsOn,如果标注有,则会设置BeanDefinition的dependsOn,设置其依赖的bean,如下在AnnotationConfigUtils注解工具类中源码如下。

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
   //省略若干代码
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
 abd.setDependsOn(dependsOn.getStringArray("value"));
}
}

上面是在注册bean元数据阶段,注册元数据阶段只是组装好bean之间的依赖,然后在真正创建bean的时候,才会进行判断,如下在AbstractBeanFactory类中的doGetBean中,会从RootBeanDefinition中取出dependsOn的值,不为空则进行bean的创建,创建bean的过程和其他bean的创建过程也是一样的。

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
           throws BeansException {
       RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
       // Guarantee initialization of beans that the current bean depends on.
       String[] dependsOn = mbd.getDependsOn();
       if (dependsOn != null) {
           for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                   throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                           "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
                   registerDependentBean(dep, beanName);
               try {
                   getBean(dep);
               } catch (NoSuchBeanDefinitionException ex) {
                   throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                           "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
           }
       }
   }

从上面可以看出,其实还是比较简单,主要就是判断是否有依赖的bean,如果有就先创建依赖的bean,没有的话就往下执行。

来源:https://juejin.cn/post/7221206168425070649

标签:Spring,注解,@DependsOn
0
投稿

猜你喜欢

  • Java接口的简单定义与实现方法示例

    2022-11-22 05:04:43
  • Flutter runApp到渲染上屏分析详解

    2023-06-27 12:09:45
  • JAVA.io读写文件方式汇总

    2022-10-14 06:32:21
  • C# WinForm导出Excel方法介绍

    2022-12-01 13:25:57
  • 关于EntityWrapper的in用法

    2023-11-29 09:02:11
  • Spring的@Autowired加到接口上但获取的是实现类的问题

    2023-08-23 21:32:21
  • 一文详解Java中Stream流的使用

    2021-08-23 11:54:51
  • javaweb 项目初始配置的方法步骤

    2021-12-23 17:34:23
  • SpringBoot配置Email发送功能实例

    2022-03-07 20:52:20
  • JAVA 字符串加密、密码加密实现方法

    2023-11-28 04:08:09
  • SpringCloud全面解析@FeignClient标识接口的过程

    2023-08-05 12:34:44
  • Spring maven filtering使用方法详解

    2021-07-02 22:14:46
  • java 使用foreach遍历集合元素的实例

    2022-11-17 09:24:58
  • Java使用通配符实现增强泛型详解

    2021-07-06 17:28:01
  • 详解springmvc常用5种注解

    2023-03-27 15:15:43
  • SpringBoot v2.2以上重复读取Request Body内容的解决方案

    2022-06-27 11:00:16
  • 使用jenkins部署springboot项目的方法步骤

    2022-06-05 05:18:31
  • Java8 Stream教程之collect()的技巧

    2023-05-01 00:45:15
  • 浅谈JVM内存溢出原因和解决思路

    2023-11-23 12:24:15
  • C# Winform实现圆角无锯齿按钮

    2022-08-30 01:11:56
  • asp之家 软件编程 m.aspxhome.com