两个Runner初始化器
两个Runner初始化器——主要作用是对component组件来执行初始化
这里的Component组件我理解为是被@Component注解修饰的类
@Component //用这个注解修饰的类,意味着这个类是spring容器中的一个组件,springboot应用会自动加载该组件。
两个Runner初始化器,实际上就是两个接口,ApplicationRunner接口和CommandLineRunner接口。这两个接口功能大致相同,实现的方法都是run()方法。
作用:
在springApplication的run()方法完成之前,这两个接口的实现类里面的run()方法会被自动调用,因此,这两个实现类非常适合在springboot项目启动之后、对外提供服务之前执行一些特定的初始化处理。
和容器初始化器的功能有些相似。不是针对容器进行初始化,而是针对应用来进行初始化。所以也叫他们两个为初始化器。
在SpringApplication的run()完成之前,Spring Boot会自动调用实现了ApplicationRunner或CommandLineRunner接口的类里面的run()方法。
换句话来说,如果一个被 @Component注解 修饰的类实现了ApplicationRunner或CommandLineRunner接口,Spring boot将会在SpringApplication的run()完成之前,自动调用该实现类里面的重写的run()方法
相当于一个钩子方法,专门用于在SpringApplication的run()完成之前,执行Component组件的初始化方法。
这里的Component组件我理解为是被@Component注解修饰的类。
——它是依赖于Spring Boot应用的本身的生命周期的
传统Spring本身可以对组件执行初始化
——实现InitalizationBean接口,或通过init-method属性来指定初始化方法。
——这种方式所依赖的是Spring容器中Bean的生命周期行为。
代码示例:
program arguments --> 程序的命令行参数
aaa, bbb, --cc=ddd
aaa是一个命令参数,bbb是一个命令参数 , --cc=ddd 也是一个参数,叫选项参数,这个–cc=ddd参数是会被springboot自动解析的。
▲ 运行Spring Boot应用的两种命令行参数
A。 传统的参数,直接列出一个一个的参数
B。 双横线开头的选项参数, 这种参数包括了选项名和选项值。
这种选项参数实际上就是对Spring Boot进行配置的参数,地位相当于application.properties文件配置,且优先级更高。
这种选项参数实际上就是对Spring Boot进行配置的参数,地位相当于application.properties文件配置,且优先级更高,会覆盖了application.properties 配置文件。
代码解释:
这里的代码只是演示项目启动时,在启动类springApplication的run()方法完成之前,ApplicationRunner接口和CommandLineRunner接口这两个接口的实现类Dog和Cat里面的run()方法会被自动调用。
具体要怎么在springApplication的run()方法完成之前做哪些额外操作或配置,需要根据实际业务去执行。
因为ApplicationRunner接口和CommandLineRunner接口的功能大致相同,区别就是ApplicationRunner接口的run方法使用 参数类型ApplicationArguments 获取参数更加方便。
下面的代码就是在演示ApplicationRunner接口通过ApplicationArguments获取参数的便利性。
在Program arguments 设置的配置的作用跟在 application.properties 配置文件设置的功能一样,但是在 Program arguments 这里设置的优先级高于 application.properties配置文件。
总结:主要演示两个Runner初始化器的实现方式,并对这两个初始化器获取参数进行比较。因为即使没有这两个初始化器,在启动配置那里对Program arguments进行的配置也没有任何影响,依然生效。所以这代码只是演示获取参数的便利性。就是能获取项目在启动的时候在Program arguments的一些配置。
其他的目前看不出有什么作用,因为也获取不到application.properties的配置。
代码:
cat
package cn.ljh.boot.domain;
import lombok.Data;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Data
@Component
public class Cat implements ApplicationRunner {
private String addr;
//ApplicationArguments 可以更方便的访问运行springboot的命令行参数
//这个run方法用于对该Bean(这个Cat类)执行初始化,此处的args就代表了运行该应用的命令行参数
@Override
public void run(ApplicationArguments args) throws Exception {
System.err.println("=====对Cat执行初始化=====");
//获取原始的参数
System.err.println("Cat的run方法,args命令行参数:" + Arrays.toString(args.getSourceArgs()));
//获取非选项参数
System.err.println("Cat的run方法,获取args里面的非选项参数:"+args.getNonOptionArgs());
//获取选项参数名
System.err.println("Cat的run方法,获取args里面的【选项参数名】:"+args.getOptionNames());
//根据选项名获取对应的选项值
for (String optionName : args.getOptionNames()) {
System.err.println("Cat的run方法,获取args里面的【选项参数值】: 选项参数名:"
+optionName + " 选项参数值:" +args.getOptionValues(optionName));
}
}
}
dog
package cn.ljh.boot.domain;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Data
@Component //用这个注解修饰,意味着这个类是spring容器中的一个组件,springboot应用会自动加载该组件。
public class Dog implements CommandLineRunner {
//将配置文件(myEnvironment.properties)里面的 myDogName 属性的值注入到这个字段里面
@Value("${myDogName}")
private String name;
//将配置文件(myEnvironment.properties)里面的 myDogAge 属性的值注入到这个字段里面
@Value("${myDogAge}")
private int age;
//无参构造器
public Dog(){
System.out.println("===创建Dog对象===");
}
//实现CommandLineRunner接口后要重写的方法
//这个run方法用于对该Bean(这个Dog类)执行初始化,此处的args就代表了运行该应用的命令行参数
@Override
public void run(String... args) throws Exception {
System.err.println("=====对Dog执行初始化=====");
System.err.println("Dog的run方法的args参数:"+Arrays.toString(args));
}
}