在某些时候我们需要SpringBoot应用启动后做一些事情。下面总结集中开机自启的方法
ApplicationRunner
实现ApplicationRunner接口
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("MyApplicationRunner run...");
}
}
CommandLineRunner
实现CommandLineRunner接口
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("CommandLineRunner run...");
}
}
追踪源码发现ApplicationRunner和CommandLineRunner的实现原理都是由run方法调用callRunners方法
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
@PostConstruct
@PostConstruct注解不是Spring提供的,与@PreDestroy , @Resource都是Java自己的注解。
PostConstruct 注解用于需要在依赖注入完成后执行任何初始化的方法。 该方法必须在类使用之前调用。 所有支持依赖注入的类都必须支持这个注解。 即使类没有请求注入任何资源,也必须调用带有 PostConstruct 注释的方法。 此注解只能注解一种方法。 应用 PostConstruct 注释的方法必须满足以下所有条件:
- 该方法不能有任何参数,除非在拦截器的情况下,在这种情况下,它需要一个由拦截器规范定义的 InvocationContext 对象。
- 在拦截器类上定义的方法必须具有以下签名之一:
void <METHOD>(InvocationContext)
Object <METHOD>(InvocationContext) throws Exception
注意:PostConstruct 拦截器方法不得抛出应用程序异常,但如果相同的拦截器方法除了生命 周期事件之外还插入业务或超时方法,则可以声明它抛出已检查的异常,包括 java.lang.Exception。 如果 PostConstruct 拦截器方法返回一个值,它会被容器忽略。
- 在非拦截器类上定义的方法必须具有以下签名:void <METHOD>()
- 应用 PostConstruct 的方法可以是公共的、受保护的、包私有的或私有的。
- 除应用程序客户端外,该方法不得是静态的。
- 该方法可能是最终的。
- 如果该方法抛出未经检查的异常,则不得将类投入使用,除非在 EJB 的情况下,EJB 可以处理异常甚至从异常中恢复。