0


SpringBoot 启动后执行功能

本文介绍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();
    }
}
  1. 类需要实现ApplicationRunner接口,实现public void run(ApplicationArguments args) throws Exception 方法
  2. 类增加@Component注解成为spring可管理的bean
  3. 多个ApplicationRunner实现类,可以通过@Order注解指定执行顺序,数越小就越先执行
  4. 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();
    }
}
  1. 类需要实现CommandLineRunner接口,实现public void run(String... args) throws Exception 方法
  2. 类增加@Component注解成为spring可管理的bean
  3. 多个CommandLineRunner实现类,可以通过@Order注解指定执行顺序,数越小就越先执行
  4. 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();
    }
}
  1. 类增加@Component注解成为spring可管理的bean
  2. 在需要执行的方法上,增加@PostConstruct注解,方法名称不一定是init
  3. 当方法执行异常,则服务启动失败
  4. 多个方法标注@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();
    }
}
  1. 类需要实现ApplicationListener接口,实现public void onApplicationEvent(E event) 方法
  2. 类增加@Component注解成为spring可管理的bean
  3. 多个CommandLineRunner实现类,可以通过@Order注解指定执行顺序,数越小就越先执行
  4. onApplicationEvent方法执行异常,则服务启动失败
  5. onApplicationEvent方法采用异步执行时,方法执行异常,服务启动不会失败
  • 四种方式比较

  1. @PostConstruct注解在类被加载的时候执行,而ApplicationRunnerCommandLineRunner接口是在工程启动后才执行
  2. ApplicationListener接口执行顺序晚于@PostConstruct注解,早于ApplicationRunnerCommandLineRunner接口
  3. 四种方式在执行方法时,只要失败,服务均不能启动
  4. ApplicationRunnerCommandLineRunner接口同时存在时,通过指定@Order注解可以改变总体的自行顺序,并不是哪个接口一定先执行
  5. @Order注解或者@Order注解的顺序一致时,ApplicationRunnerCommandLineRunner接口同时存在时,则ApplicationRunner接口优先执行
  6. 注 由于ApplicationListener接口是基于发布订阅模式的,因此可以支持异步执行,异步执行时,ApplicationListener接口早于ApplicationRunnerCommandLineRunner接口执行,但不是等到ApplicationListener接口执行完成后才执行ApplicationRunnerCommandLineRunner接口
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();
    }
}
标签: spring boot java

本文转载自: https://blog.csdn.net/weixin_48029115/article/details/133517230
版权归原作者 weixin_48029115 所有, 如有侵权,请联系我们删除。

“SpringBoot 启动后执行功能”的评论:

还没有评论