启动后,执行的任务,
方法一:通过ApplicationRunner或者CommandLineRunner的run方法完成
@Component
public class RunnerTest implements ApplicationRunner, CommandLineRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("ApplicationRunner 启动任务");
}
@Override
public void run(String... args) throws Exception {
System.out.println("CommandLineRunner 启动任务");
}
}
}
方法二:通过ApplicationListener完成
@Service
public class TestService implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// TODO Auto-generated method stub
if (event.getApplicationContext().getParent() == null) {//保证只执行一次
//需要执行的方法
System.out.println("========ApplicationListener 执行任务========");
}
}
}
方法三:通过注解实现
@PostConstruct
public void init1() {
System.out.println("@PostConstruct 启动任务");
}
我在springboot的main方法加了启动完成的输出
@SpringBootApplication
public class TestApplication{
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MonitorForDbApplication.class);
ConfigurableApplicationContext context = application.run(args);
ApplicationContextUtil.setApplicationContext(context);
System.out.println("启动完成");
}
这几种及执行的顺序如下:所有的任务执行完成后,启动才真正结束
2022-08-19 17:15:40.467 INFO 24016 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
@PostConstruct 启动任务
2022-08-19 17:15:41.314 WARN 24016 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-08-19 17:15:41.669 INFO 24016 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 10061 (http) with context path ''
========ApplicationListener 执行任务========
2022-08-19 17:15:41.686 INFO 24016 --- [ main] c.f.m.MonitorForDbApplication : Started MonitorForDbApplication in 4.614 seconds (JVM running for 5.114)
ApplicationRunner 启动任务
CommandLineRunner 启动任务
启动完成
显然通过ApplicationRunner或者CommandLineRunner实现是都程序都加载完成后执行的,不影响访问,不通担心注入@Autowired的问题。但是还是有问题,如果我在里面直接抛出异常,会影响程序的启动,直接shundown。
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("CommandLineRunner 启动任务");
throw new RuntimeException();
2022-08-19 17:30:05.536 ERROR 15784 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:785) ~[spring-boot-2.6.10.jar:2.6.10]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:766) ~[spring-boot-2.6.10.jar:2.6.10]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-2.6.10.jar:2.6.10]
at com.fdway.monitorForDB.MonitorForDbApplication.main(MonitorForDbApplication.java:22) [classes/:na]
Caused by: java.lang.RuntimeException: null
at com.fdway.monitorForDB.ScheduledService.run(ScheduledService.java:57) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:782) ~[spring-boot-2.6.10.jar:2.6.10]
... 3 common frames omitted
2022-08-19 17:30:05.657 INFO 15784 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-08-19 17:30:05.659 INFO 15784 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-08-19 17:30:05.666 INFO 15784 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
说明启动CommandLineRunner的执行其实是整个应用启动的一部分,此时CommandLineRunner的run方法执行时抛出异常,直接影响主程序的启动。
解决办法:
这样的问题该如何解决呢?这个操作影响了主线程,那么我们是否可以重新开启一个线程,让他单独去做我们想要做的操作呢。
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
new Thread(){
public void run() {
System.out.println("CommandLineRunner 启动任务");
throw new RuntimeException();
}
}.start();
}
2022-08-19 17:36:28.404 INFO 21428 --- [ main] c.f.m.MonitorForDbApplication : Started MonitorForDbApplication in 4.644 seconds (JVM running for 5.133)
CommandLineRunner 启动任务
启动完成
Exception in thread "Thread-2" java.lang.RuntimeException
at com.fdway.monitorForDB.ScheduledService$1.run(ScheduledService.java:60)
这样既解决了报错影响程序的问题,又解决了程序启动过慢的问题。