在应用 Spring Boot 开发的工作中,咱们常常会须要遇到一种性能需要,比方在服务启动时候,去加载一些配置,去申请一下其余服务的接口。Spring Boot 给咱们提供了三种罕用的实现办法:第一种是实现 CommandLineRunner 接口,第二种是实现 ApplicationRunner 接口
第三种是应用注解:@PostConstruct
1、CommandLineRunner
1、CommandLineRunner 执行的工夫节点是在 Application 实现初始化工作之后。2、CommandLineRunner 在有多个实现的时候,能够应用 @order 注解指定执行先后顺序。3、源码在:org.springframework.boot.SpringApplication#run(),能够看看
咱们先看一下 CommandLineRunner 的源码:
package org.springframework.boot;
@FunctionalInterface
public interface CommandLineRunner {void run(String... args) throws Exception;
}
SpringApplication 源码:
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}
try {listeners.running(context);
return context;
} catch (Throwable var9) {this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
callRunners 办法源码:
private void callRunners(ApplicationContext context, ApplicationArguments args) {List<Object> runners = new ArrayList();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
Iterator var4 = (new LinkedHashSet(runners)).iterator();
while(var4.hasNext()) {Object runner = var4.next();
if (runner instanceof ApplicationRunner) {this.callRunner((ApplicationRunner)runner, args);
}
if (runner instanceof CommandLineRunner) {this.callRunner((CommandLineRunner)runner, args);
}
}
}
咱们写一个例子实现:
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Order(1)
public class CommandLineRunnerTest implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {System.out.println("----CommandLineRunnerTest1 start---"+ Arrays.toString(args));
}
}
2、ApplicationRunner
ApplicationRunner 跟 CommandLineRunner 是区别是在 run 办法里接管的参数不同,CommandLineRuner 接管的参数是 String... args,而 ApplicationRunner 的 run 办法的参数是 ApplicationArguments
看看 ApplicationRunner 的源码:
package org.springframework.boot;
@FunctionalInterface
public interface ApplicationRunner {void run(ApplicationArguments args) throws Exception;
}
咱们写一个例子实现:
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
@Component
@Order(1)
public class ApplicationRunnerTest implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {System.out.println("---ApplicationRunnerTest start----");
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("[ 非选项参数]>>>" + nonOptionArgs);
Set<String> optionNames = args.getOptionNames();
for(String optionName: optionNames) {System.out.println("[ 选项参数]>>> name:" + optionName
+ ";value:" + args.getOptionValues(optionName));
}
}
}
3、@PostConstruct
@PostConstruct 是在 javaEE5 的时候引入的, 它并不是 Spring 提供的,然而 Spring 有对 @PostConstruct 的实现。并且是在对象加载完之后执行。
先看注解源码
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
咱们写一个例子实现:
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class PostConstructTest {
@PostConstruct
public void start(){System.out.println("---PostConstruct start---");
}
}
运行代码输入后果:
5、源码
https://gitee.com/Qinux/comma…
微信公众号:一凡码农
欢送交换