Springboot 启动后执行方法的四种方式

海加尔金鹰 一个菜鸟程序员的踩坑日记 本文由博客端 https://www.hjljy.cn 主动推送

最新需要在项目启动后立即执行某个方法,然后特此记录下找到的四种方式

注解 @PostConstruct

使用注解 @PostConstruct 是最常见的一种方式,存在的问题是如果执行的方法耗时过长,会导致项目在方法执行期间无法提供服务。

@Component
public class StartInit {
//
//    @Autowired   可以注入bean
//    ISysUserService userService;

    @PostConstruct
    public void init() throws InterruptedException {
        Thread.sleep(10*1000);//这里如果方法执行过长会导致项目一直无法提供服务
        System.out.println(123456);
    }
}

CommandLineRunner 接口

实现 CommandLineRunner 接口 然后在 run 方法里面调用需要调用的方法即可,好处是方法执行时,项目已经初始化完毕,是可以正常提供服务的。

同时该方法也可以接受参数,可以根据项目启动时: java -jar demo.jar arg1 arg2 arg3 传入的参数进行一些处理。详见: Spring boot CommandLineRunner 启动任务传参

@Component
public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println(Arrays.toString(args));
    }
}

实现 ApplicationRunner 接口

实现 ApplicationRunner 接口和实现 CommandLineRunner 接口基本是一样的。

唯一的不同是启动时传参的格式,CommandLineRunner 对于参数格式没有任何限制,ApplicationRunner 接口参数格式必须是:--key=value

@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        Set<String> optionNames = args.getOptionNames();
        for (String optionName : optionNames) {
            List<String> values = args.getOptionValues(optionName);
            System.out.println(values.toString());
        }
    }
}

实现 ApplicationListener

实现接口 ApplicationListener 方式和实现 ApplicationRunner,CommandLineRunner 接口都不影响服务,都可以正常提供服务,注意监听的事件,通常是 ApplicationStartedEvent 或者 ApplicationReadyEvent,其他的事件可能无法注入 bean。

@Component
public class ApplicationListenerImpl implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("listener");
    }
}

四种方式的执行顺序

注解方式 @PostConstruct 始终最先执行

如果监听的是 ApplicationStartedEvent 事件,则一定会在 CommandLineRunner 和 ApplicationRunner 之前执行。

如果监听的是 ApplicationReadyEvent 事件,则一定会在 CommandLineRunner 和 ApplicationRunner 之后执行。

CommandLineRunner 和 ApplicationRunner 默认是 ApplicationRunner 先执行,如果双方指定了 @Order 则按照 @Order 的大小顺序执行,大的先执行。

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    895 引用 • 1443 回帖 • 559 关注

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • chunjie008

    我都是继承

    ApplicationRunner

    然后写静态的线程池。

    启动一个线程 在线程里 take 队列,处理一些任务。