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