Springboot中的@Order如何使用
在spring-boot 2.6.2下測試,@Order并不會影響bean的裝載順序,聲明了@Component的類,無論是構(gòu)造方法、@PostConstruct注解聲明的方法,還是實現(xiàn)的InitializingBean接口中的afterPropertiesSet()方法,如果beanClass位于同樣的目錄層級,這些方法的調(diào)用只會受到className的順序影響:
@Component @Slf4j @Order(2) public class Bean1 implements InitializingBean { ? ? public Bean1() { ? ? ? ? log.info("construct bean1"); ? ? } ? ? @Override ? ? public void afterPropertiesSet() throws Exception { ? ? ? ? log.info("initialled bean1"); ? ? } ? ? @PostConstruct ? ? public void post() { ? ? ? ? log.info("post bean1"); ? ? } } @Component @Slf4j @Order(1) public class Bean2 implements InitializingBean { ? ? public Bean2() { ? ? ? ? log.info("construct bean2"); ? ? } ? ? @Override ? ? public void afterPropertiesSet() throws Exception { ? ? ? ? log.info("initialled bean2"); ? ? } ? ? @PostConstruct ? ? public void post() { ? ? ? ? log.info("post bean2"); ? ? } } /* 結(jié)果打印順序: construct bean1 post bean1 initialled bean1 construct bean2 post bean2 initialled bean2 */
觀察@Order的注解說明,第一句寫著: @Order defines the sort order for an annotated component. 提到這個注解只是對component排序,那么哪里會收到這個排序數(shù)值的影響呢?
這里先改造一下代碼:
public interface IBean { ? ? void work(); } @Component @Slf4j @Order(2) public class Bean1 implements InitializingBean,CommandLineRunner,IBean { ? ? public Bean1() { ? ? ? ? log.info("construct bean1"); ? ? } ? ? @Override ? ? public void afterPropertiesSet() throws Exception { ? ? ? ? log.info("initialled bean1"); ? ? } ? ? @PostConstruct ? ? public void post() { ? ? ? ? log.info("post bean1"); ? ? } ? ? @Override ? ? public void run(String... args) throws Exception { ? ? ? ? log.info("running bean1"); ? ? } ? ? @Override ? ? public void work() { ? ? ? ? log.info("bean1 is working"); ? ? } } @Component @Slf4j @Order(1) public class Bean2 implements InitializingBean, CommandLineRunner, IBean { ? ? public Bean2() { ? ? ? ? log.info("construct bean2"); ? ? } ? ? @Override ? ? public void afterPropertiesSet() throws Exception { ? ? ? ? log.info("initialled bean2"); ? ? } ? ? @PostConstruct ? ? public void post() { ? ? ? ? log.info("post bean2"); ? ? } ? ? @Override ? ? public void run(String... args) throws Exception { ? ? ? ? log.info("running bean2"); ? ? } ? ? @Override ? ? public void work() { ? ? ? ? log.info("bean2 is working"); ? ? } } @Service @RequiredArgsConstructor public class TestService { ? ? private final List<IBean> beans; ? ? public void test(){ ? ? ? ? beans.forEach(IBean::work); ? ? } }
啟動之后執(zhí)行TestService的test方法,得到如下順序的日志:
construct bean1
post bean1
initialled bean1
construct bean2
post bean2
initialled bean2
running bean2
running bean1
bean2 is working
bean1 is working
作一下說明,@Order會影響依賴注入的順序,如果存在同樣類型的多個bean,且依賴聲明使用了List<BeanInterface>,會將所有bean實例按照Order聲明的順序放入一個ArrayList中注入,如果用的是Collection或者Set則無效,因為類型本身無序。
而CommandLineRunner聲明的run方法,會在bean被IOC容器裝配完成之后被調(diào)用,方法注釋簡單明了的一句Callback used to run the bean可以理解為bean實例真正構(gòu)建完成之后的回調(diào)方法,而這個方法會受到@Order的順序影響,效果前面日志中已經(jīng)體現(xiàn),這里貼一下類注釋:
Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or @Order annotation.
除了以上兩種用法,@Aspect聲明的切面類、繼承了OncePerRequestFilter的過濾器等,它們的作用順序也會受到Order的影響。
注意:如果@Order注解配置在了@Configuration修飾的配置類中的@Bean方法修飾的方法上時,指定順序并不會生效
順便提一下另外一個注解:@Priority,以上@Order能起作用的地方,換成@Priority一樣會生效,但在一種情況下,它的作用和@Order大為不同:
同一個接口類型有多個不同的bean實現(xiàn)類時,注入依賴時使用集合聲明不會報錯,但聲明為單體類型時,如果各個Bean類使用了@Order聲明,就會報required a single bean, but x were found的錯誤,這時有兩種方法可以解決問題,一是在其中一個Bean類加上@Primary的注解聲明為首要類型,另外一個就是把Order改成Priority,優(yōu)先級最高的那個bean會被當作primary來對待。
到此這篇關(guān)于Springboot中的@Order如何使用的文章就介紹到這了,更多相關(guān)Springboot @Order內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring中REST和RESTful的區(qū)別以及基本實現(xiàn)
本文主要介紹了spring中REST和RESTful的區(qū)別以及基本實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04IDEA2022版本創(chuàng)建maven?web項目的兩種方式詳解
創(chuàng)建maven?web項目有兩種方式,一種是使用骨架方式,一種是不使用骨架的方式,本文結(jié)合實例代碼給大家介紹了IDEA2022版本創(chuàng)建maven?web項目的兩種方式,需要的朋友可以參考下2023-02-02關(guān)于spring5的那些事:@Indexed 解密
這篇文章主要介紹了關(guān)于spring5的那些事:@Indexed 解密,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Java Date類常用示例_動力節(jié)點Java學院整理
在JDK1.0中,Date類是唯一的一個代表時間的類,但是由于Date類不便于實現(xiàn)國際化,所以從JDK1.1版本開始,推薦使用Calendar類進行時間和日期處理。這里簡單介紹一下Date類的使用,需要的朋友可以參考下2017-05-05