spring之@DependsOn注解

目录

1、学习指引

2、注解说明 

2.1、注解源码 

2.2、注解使用场景

3、使用案例

3.1、标注到类上的案例

3.1.1、新建DependsOnClassA类

3.1.2、新建DependsOnClassB类

3.1.3、新建DependsOnConfig类

3.1.4、新建DependsOnTest类

3.1.5、测试DependsOnTest类

3.2、标注到方法上的案例

3.2.1、新建DependsOnMethodA类

3.2.2、新增DependsOnMethodB类

3.2.3、修改DependsOnConfig类

3.2.4、测试DependsOnTest类


1、学习指引

Spring创建Bean时如何指定Bean的依赖顺序呢?

        在实际开发项目的过程中,经常会遇到这样一种场景:在开发一个A功能模块时,这个A功能模块可能会依赖另一个B功能模块。此时,就需要先开发B功能模块,然后在开发A功能模块,在A功能模块中调用B功能模块的功能。

        在Spring中创建Bean对象也是如此,可以通过某种方式指定Spring中创建Bean的依赖顺序,Spring会根据创建Bean的依赖顺序来创建对应的Bean对象。这个指定创建Bean依赖顺序的注解就是@DependsOn注解。


2、注解说明 

        @DependsOn注解是Spring中提供的一个指定Spring创建Bean的依赖顺序的注解。例如,在Spring中需要创建A对象和B对象,可以使用@DependsOn注解指定创建A对象时依赖B对象,此时,在Spring中就会先创建B对象,然后再创建A对象。

2.1、注解源码 

@DependsOn注解可以标注到类或方法上,可以控制bean的创建、初始化和销毁方法的执行顺序。源码详见:org.springframework.context.annotation.DependsOn。

/**
 * @author Juergen Hoeller
 * @since 3.0
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
 String[] value() default {};
}

从@DependsOn注解的源码可以看出,@DependsOn注解是从Spring 3.0版本开始提供的注解。其中,只提供了一个String数组类型的value属性,含义如下所示。

  • value:表示指定的Bean的唯一标识,被指定的Bean会在Spring创建当前Bean之前被创建。

2.2、注解使用场景

        @DependsOn注解主要用于指定当前Bean对象所依赖的其他Bean对象。Spring在创建当前Bean之前,会先创建由@DependsOn注解指定的依赖Bean,在Spring中使用@DependsOn注解的场景通常会有以下几种场景:

  • 在某些情况下,Bean不是通过属性构造函数参数显式依赖于另一个Bean的,但是却需要在创建一个Bean对象之前,需要先创建另一个Bean对象,此时就可以使用@DependsOn注解。
  • 在单例Bean的情况下@DependsOn既可以指定初始化依赖顺序,也可以指定Bean相应的销毁执行顺序
  • @DependsOn注解可标注到任何直接或间接带有@Component注解的Bean或标注到@Bean注解的方法上,可以控制Bean的创建、初始化和销毁方法执行顺序。
  • 观察者模式可以分为事件,事件源和监听器三个组件,如果在Spring中需要实现观察者模式时,就可以使用@DependsOn注解实现监听器的Bean对象在事件源的Bean对象之前被创建。

3、使用案例

Spring的@DependsOn注解可以标注到类或方法上,所以,本节会列举@DependsOn注解标注到类和方法上两个案例 

3.1、标注到类上的案例

本节,主要使用@DependsOn注解标注到类上来实现Spring创建Bean的依赖顺序案例,具体实现步骤如下所示。

3.1.1、新建DependsOnClassA类

@Component(value = "dependsOnClassA")
@DependsOn(value = {"dependsOnClassB"})
public class DependsOnClassA {
    private final Logger logger = LoggerFactory.getLogger(DependsOnClassA.class);
    public DependsOnClassA(){
        logger.info("执行DependsOnClassA的构造方法");
    }
}

 可以看到,DependsOnClassA类上使用@Component注解标注,并且指定了Bean的名称为dependsOnClassA,以及使用@DependsOn注解指定了依赖的Bean名称为dependsOnClassB。

3.1.2、新建DependsOnClassB类

@Component(value = "dependsOnClassB")
public class DependsOnClassB {
    private final Logger logger = LoggerFactory.getLogger(DependsOnClassB.class);
    public DependsOnClassB(){
        logger.info("执行DependsOnClassB的构造方法");
    }
}

可以看到,在DependsOnClassB类上标注了@Component注解,指定了Bean对象的名称为dependsOnClassB。

由DependsOnClassA类和DependsOnClassB类可以看出,在Spring中创建DependsOnClassA类的对象时,会依赖DependsOnClassB类的对象。所以,在Spring中,创建DependsOnClassA类的对象之前,会先创建DependsOnClassB类的对象

3.1.3、新建DependsOnConfig类

@Configuration
@ComponentScan(basePackages = "io.binghe.spring.annotation.chapter07")
public class DependsOnConfig {
}

可以看到,DependsOnConfig类的实现比较简单,在DependsOnConfig类上标注了@Configuration注解,表示这是一个Spring的配置类,并且使用@ComponentScan注解指定了扫描的基础包名。

3.1.4、新建DependsOnTest类

public class DependsOnTest {
    public static void main(String[] args) {
        new AnnotationConfigApplicationContext(DependsOnConfig.class);
    }
}

可以看到,DependsOnTest类作为测试案例的启动类,整体实现比较简单,就是在main()方法中创建Spring的IOC容器

3.1.5、测试DependsOnTest类

运行DependsOnTest类中的main()方法,输出的结果信息如下所示。

14:56:17.977 [main] INFO DependsOnClassB - 执行DependsOnClassB的构造方法
14:56:17.978 [main] INFO DependsOnClassA - 执行DependsOnClassA的构造方法

可以看到,当@DependsOn注解标注到类上时,Spring在创建标注了@DependsOn注解的类的Bean对象之前,会先创建使用@DependsOn注解指定的Bean对象。

3.2、标注到方法上的案例

3.2.1、新建DependsOnMethodA类

public class DependsOnMethodA {
    private final Logger logger = LoggerFactory.getLogger(DependsOnMethodA.class);
    public DependsOnMethodA(){
        logger.info("执行DependsOnMethodA的构造方法");
    }
}

可以看到,DependsOnMethodA类就是一个简单的实体类,这里不再赘述。

3.2.2、新增DependsOnMethodB类

public class DependsOnMethodB {
    private final Logger logger = LoggerFactory.getLogger(DependsOnMethodB.class);
    public DependsOnMethodB(){
        logger.info("执行DependsOnMethodB的构造方法");
    }
}

可以看到,DependsOnMethodB类就是一个简单的实体类,这里不再赘述。

3.2.3、修改DependsOnConfig类

在DependsOnConfig类中使用@Bean注解分别创建DependsOnMethodA类和DependsOnMethodB类的Bean对象,如下所示。

@DependsOn(value = {"dependsOnMethodB"})
@Bean(value = "dependsOnMethodA")
public DependsOnMethodA dependsOnMethodA(){
    return new DependsOnMethodA();
}

@Bean(value = "dependsOnMethodB")
public DependsOnMethodB dependsOnMethodB(){
    return new DependsOnMethodB();
}

可以看到,在DependsOnConfig类中使用@Bean注解创建DependsOnMethodA类的Bean对象时,使用@DependsOn注解依赖了名称为dependsOnMethodB的Bean对象。

3.2.4、测试DependsOnTest类

运行DependsOnTest类中的main()方法,输出的结果信息如下所示。

15:16:24.523 [main] INFO DependsOnClassB - 执行DependsOnClassB的构造方法
15:16:24.524 [main] INFO DependsOnClassA - 执行DependsOnClassA的构造方法
15:16:24.528 [main] INFO DependsOnMethodB - 执行DependsOnMethodB的构造方法
15:16:24.529 [main] INFO DependsOnMethodA - 执行DependsOnMethodA的构造方法

        可以看到,当@DependsOn注解标注到方法上时,Spring在执行标注了@DependsOn注解的方法创建Bean对象前,先执行其他方法来创建使用@DependsOn注解指定的Bean对象。

        通过上述两个案例得知:@DependsOn注解可以指定Spring中Bean对象创建的依赖顺序,并且Spring在创建当前Bean之前,会先创建由@DependsOn注解指定的依赖Bean

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值