1

我有一个非常简单的 Gradle ( 7.0-rc-1) 脚本来使用嵌入式 Tomcat 实例初始化单个 Spring 5“hello world”端点。原始代码取自我在互联网上找到的一个随机示例。我的示例 Gradle 项目可以在这里找到。

我不确定它是如何工作的,但是 Web 服务器以某种方式知道WebApplicationInitializer.onStartup(ServletContext)在启动时调用该方法,以便初始化 Spring。

这在 Java 8 上可以正常工作;但是当我将 Gradle 构建定义中的以下工具链规范更改为 Java 16 时失败。

java {
    toolchain {
//        languageVersion = JavaLanguageVersion.of(16)
        languageVersion = JavaLanguageVersion.of(8)
    }
}

使用 Java 8 时,Spring 已正确初始化并且端点可以正常工作。

使用 Java 16 时,onStartup()不会调用该方法,因此 Spring 没有初始化并且端点不起作用(尽管 Tomcat 仍然启动并响应错误)。

日志显示一条​​消息,但没有堆栈跟踪:

INFO: No Spring WebApplicationInitializer types detected on classpath

我需要做什么才能在 Java 16 上进行这项工作?

注意我不想用spring-boot,请不要推荐。

4

1 回答 1

2

我找到了一种解决方法,可以配置 Spring 并响应/hello端点。但我不知道它为什么起作用,或者它是否是正确的做法。

如果有人可以通过解释 Java 16 的情况来回答这个问题 - 我很乐意将其标记为已接受的答案。


解决方法

我的解决方法是以编程方式添加ServletContainerInitializer类。

所以在我刚刚调用该addWebapp()方法之前:

tomcat.addWebapp("", appBase);

我现在明确添加我的 Spring 初始化程序:

Context appContext = tomcat.addWebapp("", appBase);
appContext.addServletContainerInitializer(new SpringAppConfig(), null);

更新了 Github 上的代码

于 2021-03-27T04:09:02.247 回答