判断 webapp 启动成功
web 容器是 jetty,mvc 框架是 springmvc
webapp 启动比较耗时:连接数据库,加载数据到本地缓存;连接 zookeeper 获取配置,根据配置连接到各中间件,那么问题来了,如何知道 webapp 已经启动成功呢?
实现 ApplicationListener<ContextRefreshedEvent>
这个算是网上介绍最多的方法了,若 onApplicationEvent 方法被调用,就意味着 webapp 启动成功,代码如下
@Component
public class Welcome implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger log = LoggerFactory.getLogger(Welcome.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() != null) {
log.info("webapp started");
}
}
}
一般使用到 springmvc 的 webapp,都会配置 ContextLoaderListener,这个监听器会加载配置文件,完成 spring 容器初始化的工作,可以在它后面配置一个监听器,这个监听器的监听事件被调用,就意味着 webapp 启动成功
web.xml 配置如下
代码如下
继承 DispatcherServlet
基于 springmvc 的 webapp 都会配置 DispatcherServlet,那么我们可以继承它,并重载其 init 方法,这个方法执行完成,就意味着 webapp 启动成功,代码如下
上述三种方案实际上是有区别的,真正的 webapp 启动成功应该是第三种方案 ,即继承 DispatcherServlet,要说清楚这个问题,我们可以从一个典型的 web.xml 文件开始
为了说明问题,我们这个 web.xml 是极简的,它的执行顺序如下
加载监听器,这个加载顺序是按 web.xml 里出现的顺序,并且是同步的
当 ContextLoaderListener 加载完成,触发第一次的 onApplicationEvent,这时候所有 spring 管理的 bean 都已经是就绪状态了,这意味着数据库已经连接上了,数据也已经加载到缓存;各个中间件诸如 redis/mq/dfs 等也是可以访问的状态,但是这个时候 webapp 还没有真正完成启动,因为这个时候 DispatcherServlet 还没有加载
接下来加载 LastListener,如果要求不那么严格的话,可以近似的认为此时 webapp 已启动成功了
接下来是 MyDispatcherServlet,在其 init 方法执行中,会触发第二次的 onApplicationEvent,只有完成 init 后,webapp 才算是真正的启动完成