一、概述
在日常开发中,我们很可能会遇到这样的需求:在项目启动后做某件事情,接下来本文将举例分析几个可以参考的做法:
- 实现 ApplicationRunner 接口
- 实现 CommandLineRunner 接口
- 实现 InitializingBean 接口
- 使用 @PostConstruct 注解
- 以上4种方法的对比
二、正文
1、实现 ApplicationRunner 接口
新建一个Bean,接着实现此接口,然后在run方法里面调用需要调用的方法即可。好处是方法执行时,项目已经初始化完毕,是可以正常提供服务的。
同时该方法也可以接受参数,可以根据项目启动时: java -jar demo.jar --key=value 传入的参数进行一些处理 。
@Component
public class Bean1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("----- 执行 ApplicationRunner 的方法----");
Set<String> optionNames = args.getOptionNames();
for (String optionName : optionNames) {
List<String> values = args.getOptionValues(optionName);
System.out.println("参数名:" + optionName);
System.out.println("参数值:" + values.toString());
}
}
}
IDEA设置启动参数:
启动项目,观察日志:
总共设置了2个参数‘abc’和‘–a=b’,只识别到了‘- -a=b’,因为‘abc’不满足‘- -key=value’格式
2、实现 CommandLineRunner 接口
使用方法和ApplicationRunner一样,只是参数格式不同,项目启动时按照这种格式即可: java -jar demo.jar arg1 arg2 。
@Component
public class Bean2 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("----- 执行 CommandLineRunner 的方法----");
System.out.println("CommandLineRunner的参数:" + Arrays.toString(args));
}
}
启动项目,观察日志:
3、实现 InitializingBean 接口
这种方法跟上面两种不太一样,InitializingBean接口是在Bean的实例化过程中属性填充之后执行的,属于Bean的初始化方法,关乎Bean的生命周期
@Component
public class Bean3 implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("----- 执行 InitializingBean 的方法----");
}
}
4、使用 @PostConstruct 注解
原理和 InitializingBean 接口差不多,都是Bean的初始化方法
@Component
public class Bean3 {
@PostConstruct
public void initailize() {
System.out.println("----- 执行 @PostConstruct 的方法----");
}
}
5、以上4种方法的对比
ApplicationRunner和CommandLineRunner是在项目启动完成之后才执行,比较契合文章开头的需求,两者默认先执行ApplicationRunner,可以使用@Order注解调整顺序。
InitializingBean 和 @PostConstruct 是 Bean的初始化方法,此时项目尚未启动完成。
它们的执行顺序如下: