springboot中bean的执行顺序


如果想让springboot中的bean按照我们想要的顺序去执行,要怎么做呢?

一、使用注解@DependsOn

@DependsOn可以标注在类上面,也可以标注在方法上面。

1、标注在类上面:

定义两个配置类DependsOnConfig1,DependsOnConfig2,如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 14:51
 **/
@Configuration
public class DependsOnConfig1 {

    @Bean
    public void run11() {
        System.out.println("===========run11");
    }

    @Bean
    public void run12() {
        System.out.println("===========run12");
    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:02
 **/
@Configuration
public class DependsOnConfig2 {

    @Bean
    public void run21() {
        System.out.println("===========run21");
    }

    @Bean
    public void run22() {
        System.out.println("===========run22");
    }
}

我们先不做任何认为顺序处理,启动一下服务,打印如下:

 接着,我们在DependsOnConfig1中加入注解@DepensOn,代码如下,注解标注在类中,注解的值定义为DependsOnConfig2中run22方法的名字:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 14:51
 **/
@Configuration
@DependsOn("run22")
public class DependsOnConfig1 {

    @Bean
    public void run11() {
        System.out.println("===========run11");
    }

    @Bean
    public void run12() {
        System.out.println("===========run12");
    }
}

启动服务,日志打印如下:

 可以看到,run22方法已经在run11,run12方法之前执行了。

2、标注在方法上面:

@DependsOn注解也可以标注在方法上面,我们修改DependsOnConfig1类,把@DependsOn注解修饰在run11方法上面,代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 14:51
 **/
@Configuration
public class DependsOnConfig1 {

    @Bean
    @DependsOn("run12")
    public void run11() {
        System.out.println("===========run11");
    }

    @Bean
    public void run12() {
        System.out.println("===========run12");
    }
}

启动服务,日志打印如下:

发现run12已经在run11方法之前执行了。

二、使用@Order注解

 新建一个配置类,代码如下:

import org.springframework.context.annotation.Configuration;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
public class OrderConfig2 {

    @Configuration
    public class Run21 {
        public Run21() {
            System.out.println("=============run21");
        }
    }

    @Configuration
    public class Run22 {
        public Run22() {
            System.out.println("=============run22");
        }
    }
}

启动服务,日志打印如下:

 修改代码如下:

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
public class OrderConfig2 {

    @Configuration
    @Order(10)
    public class Run21 {
        public Run21() {
            System.out.println("=============run21");
        }
    }

    @Configuration
    public class Run22 {
        public Run22() {
            System.out.println("=============run22");
        }
    }
}

启动服务,日志打印如下:

 由此可见,将@Order标注在配置类上,是可以控制执行顺序的。

但是,上面这段代码,配置类都是同一个类的内部类,那么,我们是否可以使用@Order注解干预两个同级的类的执行顺序呢?

定义两个配置类,代码如下:

import org.springframework.context.annotation.Configuration;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
public class OrderConfig2 {

    @Configuration
    public class Run21 {
        public Run21() {
            System.out.println("=============run21");
        }
    }

    @Configuration
    public class Run22 {
        public Run22() {
            System.out.println("=============run22");
        }
    }
}
import org.springframework.context.annotation.Configuration;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:59
 **/
@Configuration
public class OrderConfig3 {

    @Configuration
    public class Run31 {
        public Run31() {
            System.out.println("=============run31");
        }
    }

    @Configuration
    public class Run32 {
        public Run32() {
            System.out.println("=============run32");
        }
    }
}

启动服务,日志打印如下:

 然后在两个配置类中分别加上@Order注解,并指定顺序,修改后的代码如下:

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
@Order(10)
public class OrderConfig2 {

    @Configuration
    public class Run21 {
        public Run21() {
            System.out.println("=============run21");
        }
    }

    @Configuration
    public class Run22 {
        public Run22() {
            System.out.println("=============run22");
        }
    }
}
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:59
 **/
@Configuration
@Order(9)
public class OrderConfig3 {

    @Configuration
    public class Run31 {
        public Run31() {
            System.out.println("=============run31");
        }
    }

    @Configuration
    public class Run32 {
        public Run32() {
            System.out.println("=============run32");
        }
    }
}

启动服务,日志打印如下:

 发现@Order注解并没有起作用。

修改代码如下:

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
@Order(10)
public class OrderConfig2 implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("==============run OrderConfig2");
    }

//    @Configuration
//    public class Run21 {
//        public Run21() {
//            System.out.println("=============run21");
//        }
//    }
//
//    @Configuration
//    public class Run22 {
//        public Run22() {
//            System.out.println("=============run22");
//        }
//    }
}
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:59
 **/
@Configuration
@Order(9)
public class OrderConfig3 implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("==============run OrderConfig3");
    }

//    @Configuration
//    public class Run31 {
//        public Run31() {
//            System.out.println("=============run31");
//        }
//    }
//
//    @Configuration
//    public class Run32 {
//        public Run32() {
//            System.out.println("=============run32");
//        }
//    }
}

启动服务,日志如下:

 发现对于两个独立的配置类,使用@Order+实现CommandLineRunner接口的方式,可以设置类执行的顺序。

为了进一步验证结论的正确性,修改将两个类的@Order注解设置的顺序值(这里我们把OrderConfig2中的值调整为8):

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @Description
 * @Author
 * @Date 2020/9/29 15:51
 **/
@Configuration
@Order(8)
public class OrderConfig2 implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("==============run OrderConfig2");
    }

//    @Configuration
//    public class Run21 {
//        public Run21() {
//            System.out.println("=============run21");
//        }
//    }
//
//    @Configuration
//    public class Run22 {
//        public Run22() {
//            System.out.println("=============run22");
//        }
//    }
}

重启服务,日志如下:

 由此可见,实现了CommandLineRunner接口的配置类,确实可以通过@Order注解进行顺序调整。

 

另外了解到还有通过传参的方式,通过参数bean先加载,达到当前类bean晚于参数bean执行的效果,读者可以自行进行验证。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM