如果想讓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執行的效果,讀者可以自行進行驗證。
