一. 背景
排查线上问题, 发现一个重要功能的全局锁线程启动延迟很高. 服务启动40分钟之后, 才能拿到锁. 排查之后发现原因是因为代码引入了高优先级的ApplicationListener代码, 导致全局锁线程启动延迟.文章来源:https://www.toymoban.com/news/detail-663415.html
二. 结论
启动顺序从高到底依次为: ApplicationListener , @EventListener, CommandLineRunner , 分别可以使用order调整排序.
但是order只能控制同类型间的启动顺序.文章来源地址https://www.toymoban.com/news/detail-663415.html
三. 伪代码
3.1. 实现ApplicationListener接口
优先级最高, 可以有多个, 同ApplicationListener类型之间, 可以通过@Order(1) 注解控制相同ApplicationListener实现的启动顺序.
import java.util.concurrent.TimeUnit;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class ApplicationListener02Test implements ApplicationListener<WebServerInitializedEvent> {
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
System.out.println("Listener : ApplicationListener02Test");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
3.2. @EventListener 注解方式
@EventListener 注解方式 优先级是低于 实现ApplicationListener的方式. 必须等实现ApplicationListener类都执行完才启动, 可以通过@Order(1) 注解控制相同@EventListener实现的启动顺序.
import java.util.concurrent.TimeUnit;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class EventListener02Test {
@EventListener
@Order(0)
public void listener(ContextRefreshedEvent event) {
System.out.println("Listener : EventListener02Test");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
3.3. 实现CommandLineRunner 方式
优先级最低. 实现CommandLineRunner接口方式 优先级是低于 @EventListener的方式. 必须等实现@EventListener类都执行完才启动, 可以通过@Order(1) 注解控制相同CommandLineRunner实现的启动顺序.
package com.netease.easyflink.monitor.listener;
import java.util.concurrent.TimeUnit;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class CommandLineRunner01Test implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Listener : CommandLineRunner01Test");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
到了这里,关于ApplicationListener , @EventListener 和 CommandLineRunner 启动顺序验证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!