如果想让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执行的效果,读者可以自行进行验证。