ApplicationRunner 是 SpringBoot 的特性。
一、使用场景🤪
当 SpringBoot 项目启动完成之后,如果我们想让程序自动执行相关业务代码的时候,我们可以使用 SpringBoot 提供调的接口ApplicationRunner。该接口中,只有一个run方法,他执行的时机是:Spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。
二、实践演示😜
根据如下代码所示,有以下几点需要注意:
- 定义一个类实现
ApplicationRunner
接口 - 使用
@Component
标记,使自定义的类成为 SpringBean 添加
@Order
注解标记执行顺序(当Spring容器中包含多个ApplicationRunner
实例时生效)@Order(10)
@Component
public class ConfigSvcRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
//你需要执行的相关业务代码
}
}
三、总结和说明🤯
自定义的类必须要注入到 Spring 容器中
- 在一个项目中,可以定义多个
ApplicationRunner
的实现类,他们的执行顺序通过注解@Order
或者再实现Ordered
接口来实现。 run()
的参数:ApplicationArguments
可以获取到当前项目执行的命令参数(比如把这个项目打成 jar 执行的时候,带的参数可以通过ApplicationArguments
获取到)。由于该方法是在容器启动完成之后才执行的,所以,这里可以从 Spring 容器中拿到其他已经注入的 Bean。
四、自定义 Nacos 的配置类🤞
```java @Order(10) @Component public class ConfigSvcRunner implements ApplicationRunner {
@Autowired private ApplicationContext applicationContext;
@Override
public void run(ApplicationArguments args) throws Exception {
//使用ApplicationContext根据类型获取Spring容器中实现了ConfigSvcListener接口的Bean
Map<String, ConfigSvcListener> beansOfType = applicationContext.getBeansOfType(ConfigSvcListener.class);
//调用每个Bean的onMessage方法,该方法的作用是为其每个类注册监听器
if (MapUtils.isNotEmpty(beansOfType)) {
beansOfType.forEach((k, v) -> v.onMessage());
}
}
}
public abstract class ConfigSvcListener { private final Logger logger = LoggerFactory.getLogger(getClass());
public void onMessage() {
String dataId = getConfigFile();
String group = getDefaultGroup();
Properties properties = new Properties();
properties.put("serverAddr", getServerAddr());
ConfigService configService = null;
try {
configService = NacosFactory.createConfigService(properties);
} catch (NacosException e) {
logger.error(e.getMessage(), e);
}
String content = null;
try {
content = configService.getConfig(dataId, group, 5000);
} catch (NacosException e) {
logger.error(e.getMessage(), e);
}
//logger.info("load {} success, content is {}", getConfigFile(), content);
//初始化配置
initCfg(getConfigFile(), content);
try {
configService.addListener(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String content) {
//logger.info("receive {} success, content is {}", getConfigFile(), content);
//更新配置
refreshCfg(getConfigFile(), content);
}
@Override
public Executor getExecutor() {
return null;
}
});
} catch (NacosException e) {
logger.error(e.getMessage(), e);
}
}
protected abstract String getServerAddr();
protected abstract String getDefaultGroup();
protected abstract String getConfigFile();
protected abstract void initCfg(String config, String content);
protected abstract void refreshCfg(String config, String content);
} ```