Hello Everyone ! Time travels so fast ,Today is Friday !
SpringBoot方便了对Spring项目的开发整合,有时候我们在项目启动时会需要初始化一些东西,比如读取配置,记录开始时间一些需求,Spring Boot 提供了 两个接口 ApplicationRunner ,CommandLineRunner
。通过实现接口中的run方法可以进行项目启动的初始化
ApplicationRunner
@FunctionalInterface
public interface ApplicationRunner {
/**
* Callback used to run the bean.
* @param args incoming application arguments
* @throws Exception on error
*/
void run(ApplicationArguments args) throws Exception;
}
CommandLineRunner
@FunctionalInterface
public interface CommandLineRunner {
/**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception;
}
两者都是函数式接口 只存在一个方法。 唯一的区别时参数类型不同,前者时数组,后者时字符串
下面是实现Code 项目会在启动时,读取所有url添加到 allUrl 对象中
初始化加载url集合
@Component
public class InitUrlConfig implements ApplicationRunner {
@Resource
WebApplicationContext applicationContext;
public static List<String> allUrl;
@Override
public void run(ApplicationArguments args) throws Exception {
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
// 获取url与类和方法的对应信息
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
List<String> urlList = new ArrayList<>();
for (RequestMappingInfo info : map.keySet()) {
// 获取url的Set集合,一个方法可能对应多个url
Set<String> patterns = info.getPatternsCondition().getPatterns();
urlList.addAll(patterns);
}
allUrl = urlList;
}
}
接口简单使用
@Component
@Order(1)
public class InitConfig implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
System.out.println("ApplicationRunner");
}
@Bean
public String Init(){
System.out.println("方法的初始化");
return "初始化";
}
}
@Component
@Order(2)
public class InitOrderConfig implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
System.out.println("Application2");
}
}
执行结果
结论
@order
可以为初始化的各个run提供顺序 值越小越先执行 在不加@order
注解时最后执行 执行顺序在加载Bean之后 @CommandLineRunner
也类似