亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文詳解SpringBoot中CommandLineRunner接口

 更新時(shí)間:2023年10月31日 10:41:49   作者:fking86  
Spring Boot的CommandLineRunner接口是一個(gè)函數(shù)式接口,用于在Spring Boot應(yīng)用程序啟動(dòng)后執(zhí)行一些初始化操作,它提供了一個(gè)run方法,該方法在應(yīng)用程序啟動(dòng)后被調(diào)用,本文給大家詳細(xì)介紹了SpringBoot中CommandLineRunner接口,需要的朋友可以參考下

前言

Spring Boot的CommandLineRunner接口是一個(gè)函數(shù)式接口,用于在Spring Boot應(yīng)用程序啟動(dòng)后執(zhí)行一些初始化操作。它提供了一個(gè)run方法,該方法在應(yīng)用程序啟動(dòng)后被調(diào)用。

使用CommandLineRunner接口,可以在應(yīng)用程序啟動(dòng)后執(zhí)行一些必要的初始化操作,例如加載配置文件、初始化數(shù)據(jù)庫(kù)連接、創(chuàng)建默認(rèn)數(shù)據(jù)等??梢酝ㄟ^(guò)實(shí)現(xiàn)CommandLineRunner接口,并重寫(xiě)run方法來(lái)定義自己的初始化邏輯。

實(shí)例

導(dǎo)入庫(kù)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.0</version>
</parent>

<groupId>org.example</groupId>
<artifactId>springboot-CommandLineRunner</artifactId>
<version>1.0-SNAPSHOT</version>

<name>Spring Boot banner</name>
<description>Spring Boot and commandLineRunner</description>

<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

application.yaml

server:
  port: 8080

spring:
  profiles:
    active: dev

Runner

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class Runner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        log.info("The Runner start to initialize ...");
    }
}

SpringBootCommandLineRunnerApplication

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Slf4j
public class SpringBootCommandLineRunnerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootCommandLineRunnerApplication.class, args);
        log.info("The service to end");
    }
}

執(zhí)行結(jié)果

image-20231030003209704

在上面的示例中,我們創(chuàng)建了一個(gè)名為MyCommandLineRunner的類(lèi),并實(shí)現(xiàn)了CommandLineRunner接口。在run方法中,我們可以編寫(xiě)需要在應(yīng)用程序啟動(dòng)后執(zhí)行的初始化邏輯。

需要注意的是,實(shí)現(xiàn)CommandLineRunner接口的類(lèi)需要被Spring容器掃描到,可以使用@Component注解或其他方式將其注冊(cè)為Spring Bean。

先后順序示例

可以通過(guò)@Order()來(lái)設(shè)置Runner的先后順序,在上面例子的基礎(chǔ)上增加

OrderRunner1

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
@Slf4j
public class OrderRunner1 implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        log.info("The OrderRunner1 start to initialize ...");
    }
}

OrderRunner2

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(2)
@Slf4j
public class OrderRunner2 implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        log.info("The OrderRunner2 start to initialize ...");
    }
}

執(zhí)行結(jié)果

image-20231030003553969

通常用法

image-20231030004258880

加載初始化數(shù)據(jù)

可以實(shí)現(xiàn)CommandLineRunner接口,在run方法中加載一些初始化數(shù)據(jù)到數(shù)據(jù)庫(kù)等。適合做一些數(shù)據(jù)預(yù)加載工作。

示例

@Component
public class DataInitializer implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void run(String... args) throws Exception {
        
        // 創(chuàng)建初始用戶(hù)
        User admin = new User("admin", "123456");
        userRepository.save(admin);

        User normalUser = new User("user", "123456");
        userRepository.save(normalUser);
        
        System.out.println("數(shù)據(jù)加載完畢!");
    }
}

這里創(chuàng)建了一個(gè) DataInitializer 類(lèi),實(shí)現(xiàn) CommandLineRunner 接口。在 run() 方法中,我們注入了 UserRepository,然后創(chuàng)建了兩個(gè)用戶(hù)對(duì)象保存到數(shù)據(jù)庫(kù)中。這個(gè)類(lèi)會(huì)在 Spring Boot 應(yīng)用啟動(dòng)完成后執(zhí)行,從而實(shí)現(xiàn)了數(shù)據(jù)預(yù)加載的效果。通過(guò) CommandLineRunner,我們可以靈活地在 Spring Boot 啟動(dòng)時(shí)進(jìn)行一些初始化操作,如預(yù)先加載測(cè)試數(shù)據(jù)、插入管理員賬戶(hù)等,很好地增強(qiáng)了應(yīng)用的功能。

假設(shè)我們有一個(gè)User模型和用戶(hù)Repository,需要在Spring Boot啟動(dòng)時(shí)預(yù)加載幾個(gè)用戶(hù)數(shù)據(jù),可以這樣使用CommandLineRunner:

@Component
public class DataInitializer implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void run(String... args) throws Exception {
        
        // 清除所有數(shù)據(jù)
        userRepository.deleteAll(); 
        
        // 創(chuàng)建幾個(gè)用戶(hù)
        User user1 = new User("John", "john@example.com");
        User user2 = new User("Mary", "mary@example.com");
        
        userRepository.save(user1);
        userRepository.save(user2);
        
        // 打印已保存用戶(hù)數(shù)
        System.out.println("Number of users saved: " + userRepository.count());
    }

}

這里我們實(shí)現(xiàn)了CommandLineRunner接口,然后注入U(xiǎn)serRepository bean。在run方法中,首先清空所有數(shù)據(jù),然后創(chuàng)建兩個(gè)用戶(hù)對(duì)象并保存,最后打印已保存的用戶(hù)數(shù)。這樣在Spring Boot應(yīng)用啟動(dòng)完成后,就會(huì)自動(dòng)執(zhí)行run方法,預(yù)加載指定的用戶(hù)數(shù)據(jù)。

啟動(dòng)后打印應(yīng)用信息

可以打印出一些應(yīng)用啟動(dòng)信息,如啟動(dòng)端口、運(yùn)行環(huán)境信息等,用于確認(rèn)應(yīng)用配置。

示例

@Component
@Slf4j
public class AppInfoPrinter implements CommandLineRunner {

    @Autowired
    private Environment environment;
    @Override
    public void run(String... args) throws Exception {

        log.info("========= 打印啟動(dòng)信息 =========");
        // 打印應(yīng)用端口
        log.info(("端口號(hào): " + environment.getProperty("server.port")));
        // 打印當(dāng)前環(huán)境
        log.info("當(dāng)前環(huán)境: " + environment.getProperty("spring.profiles.active"));
        // 打印JDK版本
        log.info("JDK 版本: " + System.getProperty("java.version"));
        log.info("========= 打印啟動(dòng)信息結(jié)束 =========");

    }

}

執(zhí)行打印結(jié)果

image-20231030011038160

啟動(dòng)異步任務(wù)

可以使用多線程啟動(dòng)一些異步任務(wù),進(jìn)行后臺(tái)數(shù)據(jù)處理等復(fù)雜業(yè)務(wù)邏輯。

示例

@Component
@Slf4j
public class AsyncTaskRunner implements CommandLineRunner {

    @Autowired
    private AsyncTaskService asyncTaskService;

    @Override
    public void run(String... args) throws Exception {
        log.info("========= 執(zhí)行任務(wù) =========");
        // 在新線程中執(zhí)行任務(wù)
        new Thread(() -> {
            asyncTaskService.doTaskOne();
            asyncTaskService.doTaskTwo();
            asyncTaskService.doTaskThree();
        }).start();
    }

}

@Service
@Slf4j
class AsyncTaskService {

    public void doTaskOne() {
        log.info("執(zhí)行任務(wù)1");
    }

    public void doTaskTwo() {
        log.info("執(zhí)行任務(wù)2");
    }

    public void doTaskThree() {
        log.info("執(zhí)行任務(wù)3");
    }
}

執(zhí)行結(jié)果

[           main] org.example.runner.AsyncTaskRunner       : ========= 執(zhí)行任務(wù) =========
[       Thread-1] org.example.runner.AsyncTaskService      : 執(zhí)行任務(wù)1
[       Thread-1] org.example.runner.AsyncTaskService      : 執(zhí)行任務(wù)2
[       Thread-1] org.example.runner.AsyncTaskService      : 執(zhí)行任務(wù)3

接口健康檢查

可以調(diào)用并驗(yàn)證依賴(lài)服務(wù)的健康狀態(tài),如果不正??梢越K止Spring Boot啟動(dòng)。

示例

@Component
@Slf4j
public class HealthCheckRunner implements CommandLineRunner {

    @Autowired
    private DatabaseService databaseService;

    @Autowired
    private MessageQueueService messageQueueService;

    @Override
    public void run(String... args) throws Exception {

        if(!databaseService.isConnected()) {
            log.error("數(shù)據(jù)庫(kù)服務(wù)不可用,退出應(yīng)用!");
            System.exit(1);
        }

        if(!messageQueueService.isConnected()) {
            log.error("消息隊(duì)列服務(wù)不可用,退出應(yīng)用!");
            System.exit(1);
        }

        log.info("所有服務(wù)正常,應(yīng)用啟動(dòng)。");

    }
}

這里我們注入兩個(gè)依賴(lài)服務(wù) DatabaseService 和 MessageQueueService。在run方法中,調(diào)用它們的健康檢查方法,如果任何一個(gè)服務(wù)不可用,則直接調(diào)用System.exit(1)退出Spring Boot應(yīng)用啟動(dòng)。

外部服務(wù)調(diào)用

可以在啟動(dòng)時(shí)調(diào)用外部服務(wù),進(jìn)行驗(yàn)證、數(shù)據(jù)同步等操作。

示例

@Component
public class OtherServiceCheckRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 健康檢查的URL
        String healthCheckUrl = "http://localhost:8080/actuator/health";

        RestTemplate restTemplate = new RestTemplate();
        // 發(fā)送GET請(qǐng)求進(jìn)行健康檢查
        String response = restTemplate.getForObject(healthCheckUrl, String.class);

        // 根據(jù)響應(yīng)判斷健康狀態(tài)
        if (response.contains("\"status\":\"UP\"")) {
            System.out.println("Application is healthy");
        } else {
            System.out.println("Application is not healthy");
        }
    }
}

參數(shù)校驗(yàn)

可以對(duì)輸入的運(yùn)行參數(shù)做校驗(yàn),如果不滿足條件可以終止Spring Boot啟動(dòng)。

示例

@Component
@Slf4j
public class ParameterValidator implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 校驗(yàn)參數(shù)1
        if(args.length < 2) {
            log.error("參數(shù)不正確,請(qǐng)傳入至少2個(gè)參數(shù)!");
            System.exit(1);
        }

        // 校驗(yàn)參數(shù)2是否為數(shù)字
        if(!args[1].matches("\\d+")) {
            log.error("第二個(gè)參數(shù)必須是數(shù)字!");
            System.exit(1);
        }

        // 校驗(yàn)通過(guò),應(yīng)用繼續(xù)啟動(dòng)
        log.info("參數(shù)校驗(yàn)通過(guò),應(yīng)用啟動(dòng)中...");
    }
}

在run方法中,我們可以對(duì)main方法輸入的參數(shù)args進(jìn)行自定義校驗(yàn):

檢查參數(shù)數(shù)量校驗(yàn)參數(shù)類(lèi)型

如果參數(shù)不滿足需求,可以直接調(diào)用System.exit(1)來(lái)終止Spring Boot的啟動(dòng)。這樣就可以在應(yīng)用啟動(dòng)前驗(yàn)證參數(shù)的正確性,避免應(yīng)用啟動(dòng)后發(fā)生未知錯(cuò)誤。

動(dòng)態(tài)設(shè)置配置

可以根據(jù)運(yùn)行參數(shù)等條件動(dòng)態(tài)設(shè)置Spring Boot的配置,實(shí)現(xiàn)不同環(huán)境的適配。

示例 application.yaml

myconfig:
  foo: 十五
  bar: 1

MyConfig

@Component
@Data
@ConfigurationProperties(prefix = "myconfig")
public class MyConfig {
    private String foo;
    private int bar;

// getter和setter方法省略

    @Override
    public String toString() {
        return "MyConfig{" +
                "foo='" + foo + '\'' +
                ", bar=" + bar +
                '}';
    }
}

ConfigRunner

@Component
@EnableConfigurationProperties(MyConfig.class)
public class ConfigRunner implements CommandLineRunner {

    @Autowired
    private MyConfig myConfig;

    @Override
    public void run(String... args) throws Exception {
// 打印當(dāng)前配置
        System.out.println("Current config: " + myConfig);

// 動(dòng)態(tài)設(shè)置配置
        myConfig.setFoo("new value");
        myConfig.setBar(100);

// 打印更新后的配置
        System.out.println("Updated config: " + myConfig);
    }
}

啟動(dòng)阻塞

可以使應(yīng)用啟動(dòng)后阻塞住主線程,防止main方法直接退出,從而保持Spring Boot應(yīng)用運(yùn)行。

示例

@Component
@Slf4j
public class StartBlocker implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 加載提示信息
        log.info("正在等待管理員授權(quán)...");

        // 等待授權(quán),阻塞啟動(dòng)流程
        waitAuth();

        // 授權(quán)完成后繼續(xù)啟動(dòng)
        log.info("管理員已授權(quán),應(yīng)用啟動(dòng)中...");
    }

    private void waitAuth() {
        // 死循環(huán)模擬等待管理員操作授權(quán)
        while(true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                break;
            }
        }
    }

}

總結(jié)

通過(guò) CommandLineRunner,我們可以深度控制 Spring Boot 應(yīng)用的啟動(dòng)流程,在應(yīng)用啟動(dòng)階段增強(qiáng)各種自定義邏輯。是 Spring Boot 提供的一個(gè)很實(shí)用的擴(kuò)展點(diǎn)。

以上就是一文詳解SpringBoot中CommandLineRunner接口的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot CommandLineRunner接口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論