针对一些在应用启动后,但是实际接收请求前的执行任务比如配置加载,bean注入,可以使用ApplicationRunner or CommandLineRunner接口来实现.
这两个接口都只提供了一个 run 方法, 它会在SpringApplication.run(…) 执行完之前被调用.
使用方式:
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
如果定义了多个ApplicationRunner or CommandLineRunner,可以使用org.springframework.core.Ordered或org.springframework.core.annotation.Order注解来排执行顺序.
使用示例:
用于输出特定方法启动日志输出:
@Bean
@ConditionalOnClass(value = {CentralDogma.class, ObjectMapper.class})
public CommandLineRunner commandLineRunner(CentralDogma dogma, ObjectMapper objectMapper, BeanResolver beanResolver) {
log.info("project:{}, repo:{},filename:{}", properties.getProject(), properties.getRepo(), properties.getConfName());
Watcher watcher = dogma.fileWatcher(properties.getProject(), properties.getRepo(), Query.ofText(properties.getConfName()));
watcher.watch((revision, value) -> {
log.info("Updated to {} at {}", value, revision);
try {
List<RulesConfig> rulesConfigs = objectMapper.readValue(value.toString(), new TypeReference<List<RulesConfig>>() {
});
easyRulesEntities.setRulesConfigs(rulesConfigs);
this.easyRules = rulesContent2EasyRules(beanResolver);
} catch (JsonProcessingException e) {
e.printStackTrace();
log.error("json convert error", e);
}
});
return args -> {
log.info("init CentralDogma load easy rules conf");
};
}
常用条件注解:
@Conditional(TestCondition.class) 这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置,也可以标注在方法上面,只是对该方法启用配置。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)