ApplicationRunner 是 SpringBoot 的特性。
一、使用场景🤪
当 SpringBoot 项目启动完成之后,如果我们想让程序自动执行相关业务代码的时候,我们可以使用 SpringBoot 提供调的接口ApplicationRunner。该接口中,只有一个run方法,他执行的时机是:Spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。
二、实践演示😜
根据如下代码所示,有以下几点需要注意:
- 定义一个类实现
ApplicationRunner接口 - 使用
@Component标记,使自定义的类成为 SpringBean 添加
@Order注解标记执行顺序(当Spring容器中包含多个ApplicationRunner实例时生效)@Order(10)@Componentpublic class ConfigSvcRunner implements ApplicationRunner {@Overridepublic 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;
@Overridepublic void run(ApplicationArguments args) throws Exception {//使用ApplicationContext根据类型获取Spring容器中实现了ConfigSvcListener接口的BeanMap<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);
} ```
