本文介绍SpringBoot项目的四种启动后执行功能的方式。
方法1: ApplicationRunner 接口
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(value = 2)
public class ApplicationRunnerTest implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("========ApplicationRunner========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
- 类需要实现
ApplicationRunner
接口,实现public void run(ApplicationArguments args) throws Exception
方法 - 类增加
@Component
注解成为spring可管理的bean - 多个
ApplicationRunner
实现类,可以通过@Order
注解指定执行顺序,数越小就越先执行 - 当
run
方法执行异常,则服务启动失败
方法2: CommandLineRunner 接口
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(value = 2)
public class CommandLineRunnerTest implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("========CommandLineRunner========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
- 类需要实现
CommandLineRunner
接口,实现public void run(String... args) throws Exception
方法 - 类增加
@Component
注解成为spring可管理的bean - 多个
CommandLineRunner
实现类,可以通过@Order
注解指定执行顺序,数越小就越先执行 - 当
run
方法执行异常,则服务启动失败
方法3: @PostConstruct 注解
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
@Component
public class PostConstructTest {
@PostConstruct
public void init() {
System.out.println("========PostConstruct========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
- 类增加
@Component
注解成为spring可管理的bean - 在需要执行的方法上,增加
@PostConstruct
注解,方法名称不一定是init - 当方法执行异常,则服务启动失败
- 多个方法标注
@Component
注解,按照顺序依次执行,即使方法上标注@Order
注解。
import javax.annotation.PostConstruct;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class PostConstructTest {
@PostConstruct
@Order(value = 2)
public void init() {
System.out.println("========PostConstruct========");
}
@PostConstruct
@Order(value = 1)
public void init2() {
System.out.println("========PostConstruct2========");
}
}
虽然将两个方法上都加了
@Order
注解,并且
init2()
方法的设置顺序小于
init()
方法,但是仍然先执行
init()
方法
方法4: ApplicationListener 接口
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class ApplicationListenerTest implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("========ApplicationListener========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
- 类需要实现
ApplicationListener
接口,实现public void onApplicationEvent(E event)
方法 - 类增加
@Component
注解成为spring可管理的bean - 多个
CommandLineRunner
实现类,可以通过@Order
注解指定执行顺序,数越小就越先执行 - 当
onApplicationEvent
方法执行异常,则服务启动失败 - 当
onApplicationEvent
方法采用异步执行时,方法执行异常,服务启动不会失败
四种方式比较
@PostConstruct
注解在类被加载的时候执行,而ApplicationRunner
、CommandLineRunner
接口是在工程启动后才执行ApplicationListener
接口执行顺序晚于@PostConstruct
注解,早于ApplicationRunner
、CommandLineRunner
接口- 四种方式在执行方法时,只要失败,服务均不能启动
ApplicationRunner
、CommandLineRunner
接口同时存在时,通过指定@Order
注解可以改变总体的自行顺序,并不是哪个接口一定先执行- 无
@Order
注解或者@Order
注解的顺序一致时,ApplicationRunner
、CommandLineRunner
接口同时存在时,则ApplicationRunner
接口优先执行 - 注 由于
ApplicationListener
接口是基于发布订阅模式的,因此可以支持异步执行,异步执行时,ApplicationListener
接口早于ApplicationRunner
、CommandLineRunner
接口执行,但不是等到ApplicationListener
接口执行完成后才执行ApplicationRunner
、CommandLineRunner
接口
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class ApplicationListenerTest implements ApplicationListener<ContextRefreshedEvent>{
@Override
@Async // 已经在SpringBoot启动类增加了@EnableAsync注解
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("========ApplicationListener========");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 由于异步执行,所以方法执行失败后,仍然不会停止服务
// throw new RuntimeException();
}
}
其他
对于
@Order
注解,也可以采用Ordered
接口来实现,需要实现public int getOrder()
方法
@Component
//@Order(value = 2)
public class CommandLineRunnerTest implements CommandLineRunner ,Ordered {
@Override
public int getOrder() {
return 1;
}
@Override
public void run(String... args) throws Exception {
System.out.println("========CommandLineRunner========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
- ApplicationListener 扩展方式
由于ApplicationListener 是发布订阅模式,可以直接采用
@EventListener
注解来实现。
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class EventListenerTest {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("========EventListener========");
// 失败后,服务停止
// throw new RuntimeException();
}
}
版权归原作者 weixin_48029115 所有, 如有侵权,请联系我们删除。