Spring Boot:如何向嵌入式 tomcat 添加另一个 WAR 文件? [英] Spring Boot: How to add another WAR files to the embedded tomcat?

查看:46
本文介绍了Spring Boot:如何向嵌入式 tomcat 添加另一个 WAR 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring Boot 的内嵌 tomcat 非常好用,无论是开发还是部署.

Spring Boot's embedded tomcat is very handy, for both development and deploy.

但是如果应该添加另一个(第 3 方)WAR 文件(例如 GeoServer)怎么办?

But what if an another (3rd-party) WAR file (for example, GeoServer) should be added?

也许以下是正常程序:

  1. 安装一个普通的Tomcat服务器.
  2. 将 Spring Boot 应用程序构建为 WAR 文件,并将其添加到 Tomcat 的 webapps 文件夹中.
  3. 还将另一个(第 3 方)WAR 文件添加到 webapps 文件夹中.

但是如果可以进行以下配置就好了.

But it would be nice if the following configuration were possible.

  1. 将 Spring boot 应用程序构建为独立的 Jar,其中包括嵌入式 Tomcat.
  2. 部署 Spring Boot 应用程序 Jar.
  3. 将另一个(第 3 方)WAR 文件添加到嵌入式 Tomcat 识别的文件夹中.
  4. 使用嵌入式 Tomcat 为 Spring 启动应用程序内容和另一个 WAR 内容提供服务.

怎么做?

更新

spring boot 应用是用fat jar(=executable jar)做的时候,回答里的代码不够用.修改后的内容如下:

When the spring boot application is made of fat jar(=executable jar), the code in the answer is not enough. The revised one is as follows:

@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            try {
                Context context = tomcat.addWebapp("/foo", "/path/to/foo.war");
                WebappLoader loader =
                    new WebappLoader(Thread.currentThread().getContextClassLoader());
                context.setLoader(loader);
            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }

    };
}

由于系统类加载器无法加载fat jar 中的jar 文件,因此必须指定显式父类加载器.否则,附加的 WAR 无法加载添加 WAR 的 Spring Boot 应用程序的胖 jar 中的库 jar.

Since the jar files in a fat jar cannot be loaded by the system classloader, an explicit parent classloader must be specified. Otherwise, the additional WAR cannot load the library jars in the fat jar of the spring boot application that added the WAR.

推荐答案

您可以使用 Tomcat.addWebapp 向嵌入式 Tomcat 添加一个 war 文件.正如其 javadoc 所说,它相当于将一个 Web 应用程序添加到 Tomcat 的 Web 应用程序目录".要在 Spring Boot 中使用此 API,您需要使用自定义的 TomcatEmbeddedServletContainerFactory 子类:

You can add a war file to embedded Tomcat using Tomcat.addWebapp. As its javadoc says, it's the "equivalent to adding a web application to Tomcat's web apps directory". To use this API in Spring Boot, you need to use a custom TomcatEmbeddedServletContainerFactory subclass:

@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            // Ensure that the webapps directory exists
            new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs();

            try {
                Context context = tomcat.addWebapp("/foo", "/path/to/foo.war");
                // Allow the webapp to load classes from your fat jar
                context.setParentClassLoader(getClass().getClassLoader());
            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }

    };
}

这篇关于Spring Boot:如何向嵌入式 tomcat 添加另一个 WAR 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆