书接上文,前面在 [Spring 应用合并之路(一):摸石头过河]介绍了几种不成功的经验,下面继续折腾…
四、仓库合并,独立容器
在经历了上面的尝试,在同事为啥不搞两个独立的容器提醒下,决定抛开 Spring Boot 内置的父子容器方案,完全自己实现父子容器。
如何加载 web
项目?
现在的难题只有一个:如何加载 web
项目?加载完成后,如何持续持有 web
项目?经过思考后,可以创建一个 boot
项目的 Spring Bean,在该 Bean 中加载并持有 web
项目的容器。由于 Spring Bean 默认是单例的,并且会伴随 Spring 容器长期存活,就可以保证 web
容器持久存活。结合 Spring 扩展点概览及实践 中介绍的 Spring 扩展点,有两个地方可以利用:
1.可以利用 ApplicationContextAware 获取 boot 容器的 ApplicationContext 实例,这样就可以实现自己实现的父子容器;
2.可以利用 ApplicationListener 获取 ContextRefreshedEvent 事件,该事件表示容器已经完成初始化,可以提供服务。在监听到该事件后,来进行 web 容器的加载。
思路确定后,代码实现就很简单了:
package com.diguage.demo.boot.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
/**
* @author D瓜哥 · https://www.diguage.com
*/
@Component
public class WebLoaderListener implements ApplicationContextAware,
ApplicationListener<ApplicationEvent> {
private static final Logger logger = LoggerFactory.getLogger(WebLoaderListener.class);
/**
* 父容器,加载 boot 项目
*/
private static ApplicationContext parentContext;
/**
* 子容器,加载 web 项目
*/
private static ApplicationContext childContext;
@Override
public void s