- 需求:需要在SpringBoot项目做一些初始化工作,例如当项目运行之后就开始启动一个定时任务等等。
第一种解决方法:使用SpringBoot Application事件监听
-
ApplicationStartingEvent
: 在运行开始时但在任何处理之前发送 ApplicationStartingEvent ,但监听器和初始化程序的注册除外。 -
ApplicationEnvironmentPreparedEvent
:当在上下文中使用的 Environment 已知但在创建上下文之前发送 ApplicationEnvironmentPreparedEvent -
ApplicationPreparedEvent
:在开始刷新之前,bean 定义被加载之后发送 ApplicationPreparedEvent -
ApplicationStartedEvent
:在刷新上下文之后但在调用任何应用程序和命令行运行程序之前发送 ApplicationStartedEvent 。 -
ApplicationReadyEvent
:在调用任何应用程序和命令行运行程序后发送 ApplicationReadyEvent 。它表示应用程序已准备好为请求提供服务。 -
ApplicationFailedEvent
:如果启动时发生异常,则发送 ApplicationFailedEvent 。
下面以ApplicationPreparedEvent
为例:
- 新建
ApplicationPreparedEventListener
类实现ApplicationListener<ApplicationPreparedEvent>
package com.example.demo.listener;
import org.springframework.boot.context.event.*;
import org.springframework.context.*;
/**
* @author lijing
* @date 2019-09-06 19:16
* @description
*/
public class ApplicationPreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationPreparedEvent e) {
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("初始化");
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
}
- 在主函数里面添加事件
package com.example.demo;
import com.example.demo.listener.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
springApplication.addListeners(new ApplicationPreparedEventListener());
springApplication.run(args);
}
}
- 运行结果如下:
其他事件监听同上
第二种解决方法:使用CommandLineRunner或者ApplicationRunner
- 注意:ApplicationRunner和CommandLineRunner的执行在ApplicationReadyEvent之后
- 下面以
CommandLineRunner
为例 - 新建
MyCommandLineRunner
继承CommandLineRunner
package com.example.demo.listener;
import org.springframework.boot.*;
/**
* @author lijing
* @date 2019-09-06 23:40
* @description
*/
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("============================");
System.out.println("初始化");
System.out.println("============================");
}
}
- 主函数
package com.example.demo;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
- 运行结果如下:
两种方式的区别
-
使用第一种方式的时候应该注意不要使用自动注入,例如现在想要注入
TestService
的实例 -
TestService
package com.example.demo.service;
import org.springframework.stereotype.*;
/**
* @author lijing
* @date 2019-09-06 19:46
* @description
*/
@Service
public class TestService {
}
使用SpringBoot Application事件监听
- ApplicationPreparedEventListener
package com.example.demo.listener;
import com.example.demo.service.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.context.event.*;
import org.springframework.context.*;
/**
* @author lijing
* @date 2019-09-06 23:53
* @description
*/
public class ApplicationPreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> {
@Autowired
TestService testService;
@Override
public void onApplicationEvent(ApplicationPreparedEvent applicationPreparedEvent) {
System.out.println("====================================");
System.out.println(testService);
System.out.println("====================================");
}
}
- 运行结果:
- 可以发现testService为null
使用CommandLineRuner
- MyCommandLineRunner
package com.example.demo.listener;
import com.example.demo.service.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.*;
import org.springframework.stereotype.*;
/**
* @author lijing
* @date 2019-09-06 23:40
* @description
*/
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Autowired
TestService testService;
@Override
public void run(String... args) throws Exception {
System.out.println("============================");
System.out.println(testService);
System.out.println("============================");
}
}
- 运行结果:
- 可以发现
testService
正常注入
注意: 如果有多个类实现CommandLineRunner接口,需要按照一定的顺序去执行,那么就需要在实体类上使用一个@Order注解(或者实现Order接口)来表明顺序