SpringBoot 启动成功初始化数据

本章节将介绍通过实现 CommandLineRunner 和 ApplicationRunner 接口,实现 Spring Boot 启动成功初始化数据。

如果你有一些资源需要在 Spring Boot 启动成功后才去加载,如:预加载配置、加载定时任务、初始化工作等。这些可以通过 Spring Boot 给我们提供的CommandLineRunner 接口和 ApplicationRunner 接口实现。

CommandLineRunner 接口

CommandLineRunner接口是在容器启动成功后的最后一步回调(类似开机自启动)。接口的源码如下:

package org.springframework.boot;

@FunctionalInterface
public interface CommandLineRunner {

    void run(String... args) throws Exception;

}

该接口只定义了一个 run() 方法,且该方法仅仅接收一个字符串数组。如果我们需要在 Spring Boot 启动成功后做些什么,如:初始化数据,需要实现该接口,实现 run 方法。例如:

package com.huangx.springboot.service;


import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

/**
 * SpringBoot启动完成后自动运行
 */
@Service
public class AfterServiceStartedOther implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("AfterServiceStartedOther");
        for(String arg : args) {
            System.out.println(arg);
        }
    }

}

在运行 Spring Boot 时,添加参数,如下图:

SpringBoot 启动成功初始化数据_第1张图片

程序运行结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v2.0.1.RELEASE)

……

2020-07-20 23:04:31.759  INFO 16772 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729

……

AfterServiceStartedOther

name1

name2

name3

从上面实例可以知道,run 方法的参数实际是上就是我们运行程序传递的参数。

ApplicationRunner 接口

CommandLineRunner接口和ApplicationRunner 接口基本一样,区别在于两者接收的参数不一样。CommandLineRunner 的参数是最原始的参数,没有做任何处理;而ApplicationRunner的参数是ApplicationArguments,对原始参数做了进一步的封装。下面通过实例进行说明:

package com.huangx.springboot.service;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * SpringBoot启动完成后自动运行
 */
@Service
public class AfterServiceStarted implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("AfterServiceStarted");
        for(String name : args.getOptionNames()) {
            System.out.println(name + "=" + args.getOptionValues(name));
        }
    }

}

假如我们在这里配置了一些启动参数 --env=dev --level=debug,如下图:

SpringBoot 启动成功初始化数据_第2张图片

然后运行程序,结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v2.0.1.RELEASE)

……

2020-07-20 23:14:16.307  INFO 21612 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729

……

AfterServiceStarted

level=[debug]

env=[dev]

如果使用 CommandLineRunner 实现上面实例,则 CommandLineRunner 只获取 --env=dev --level=debug 字符串。而 ApplicationRunner 可以将 --env=dev --level=debug 解析为 Key-Value,使得我们可以直接通过 key 来获取 value。

注意:ApplicationRunner 解析的参数必须使用“--”开头(双横线),否则不会解析。

设置 CommandLineRunner 和 ApplicationRunner 接口启动顺序

CommandLineRunner 和 ApplicationRunner 接口的工作方式类似,如果有多个启动回调接口实现类,我们还可以通过添加 @Order 注解指定顺序。

例如,我们将上面的 AfterServiceStarted 设置为第一个启动,AfterServiceStartedOther 设置为第二个启动。如下:

AfterServiceStarted.java

package com.huangx.springboot.service;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * SpringBoot启动完成后自动运行
 */
@Order(1)
@Service
public class AfterServiceStarted implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("AfterServiceStarted");
        for(String name : args.getOptionNames()) {
            System.out.println(name + "=" + args.getOptionValues(name));
        }
    }

}

AfterServiceStartedOther.java

package com.huangx.springboot.service;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
 * SpringBoot启动完成后自动运行
 */
@Order(2)
@Service
public class AfterServiceStartedOther implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("AfterServiceStartedOther");
        for(String arg : args) {
            System.out.println(arg);
        }
    }

}

运行结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  '  |____| .__|_| |_|_| |_\__, | / / / /

 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::        (v2.0.1.RELEASE)

 ……

 2020-07-20 23:23:58.084  INFO 19048 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729

 ……

AfterServiceStarted

level=[debug]

env=[dev]

AfterServiceStartedOther

--env=dev

--level=debug

你可能感兴趣的:(Spring,Boot)