在应用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;@FunctionalInterfacepublic 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;@FunctionalInterfacepublic 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;@Componentpublic class PostConstructTest { @PostConstruct public void start(){ System.out.println("---PostConstruct start---"); }}
运行代码输入后果 :
5、源码
https://gitee.com/Qinux/comma...
微信公众号:一凡码农欢送交换