Spring Boot (JAR),具有多个调度程序 servlet,用于使用 Spring Data REST 的不同 REST API

2023-11-23

我有一个项目,它使用 Spring Boot 生成一个可执行 JAR,该 JAR 通过 Spring Data REST 公开 REST API。它还与 Spring Security OAuth 集成。效果很好。我的问题如下,

我希望为 REST API 提供不同的模块,仅当具有 JPA 存储库的对应 JAR 位于类路径中(它已被定义为依赖项)时才启用这些模块。

问题是我希望他们彼此独立。我希望能够在具有不同映射的不同调度程序 servlet 下为它们提供服务,这样我就可以为每个调度程序 servlet 指定不同的 baseUri,并为资源发现提供不同的根 URL。

我会试着说得更清楚:

  • API模块A:

    • 例如包含资源 X 和 Y 的 XRespository 和 YRespository 的 JAR。
    • 调度程序 servlet A.
    • Servlet 映射:/api/moduleS/
    • Spring Data REST 的基本 URI:/api/moduleS/
    • 如果我检查 URL /api/moduleA/ 我应该发现资源 X 和 Y。
  • API模块B:

    • 包含资源 P 和 Q 的 PRespository 和 QRespository 等 JAR。
    • 调度程序 servlet B.
    • Servlet 映射:/api/moduleB/
    • Spring Data REST 的基本 URI:/api/moduleB/
    • 如果我检查 URL /api/moduleB/ 我应该发现资源 P 和 Q。
  • 更多模块...

除此之外,我可以有另一个调度程序 servlet,其中我保存 /oauth/* 端点以及其他自定义控制器,并且安全配置必须对所有 (/*) 正常工作

我知道我可以通过 ServletRegistrationBean 定义更多调度程序 servlet,但我不知道如何附加到每个不同的 spring 数据休息配置。

我还尝试使用 SpringApplicationBuilder 使用分层应用程序上下文来实现此目的,方法是在每个子上下文中定义每个调度程序 servlet、每个 RepositoryRestMvcConfiguration 的配置,并让每个 @EnableJpaRepositories 注释定义要扫描的不同包。无论如何,我什至无法加载上下文,因为它们不是作为 WebApplicationContext 创建的,因此失败,因为没有可用的 ServletContext。

有什么帮助/建议吗?提前致谢。


我不久前找到了解决方案,但我忘了在这里分享,所以感谢 Jan 提醒我。

我通过使用具有不同配置的新 Web 应用程序上下文创建和注册多个调度程序 servlet 来解决这个问题(存储库RestMvcConfiguration)和一个公共父级,它是 Spring Boot 应用程序的根应用程序上下文。为了根据类路径中包含的不同 jar 自动启用 API 模块,我或多或少模拟了 Spring Boot 的功能。

该项目分为几个 gradle 模块。像这样的东西:

  • 项目服务器
  • 项目-api-自动配置
  • 项目模块 a-api
  • 项目模块 b-api
  • ...
  • 项目模块 n-api

该模块项目服务器是主要的。它声明了对项目-api-自动配置,同时它排除了传递依赖项目-api-自动配置 on 项目模块-?-api 模块.

Inside 项目服务器.gradle:

dependencies {
    compile (project(':project-api-autoconfigure')) {
        exclude module: 'project-module-a-api'
        exclude module: 'project-module-b-api'
        ...
    }
    ...
}

项目-api-自动配置依赖于所有 API 模块,因此依赖关系将如下所示项目-api-自动配置.gradle:

dependencies {
    compile project(':project-module-a-api')
    compile project(':project-module-b-api')
    ...
}

项目-api-自动配置是我为每个 API 模块创建具有自己的 Web 应用程序上下文的调度程序 servlet bean 的地方,但此配置以位于每个 API 模块 jar 内的每个 API 模块的配置类为条件。

我创建了每个自动配置类继承的抽象类:

public abstract class AbstractApiModuleAutoConfiguration<T> {

    @Autowired
    protected ApplicationContext applicationContext;

    @Autowired
    protected ServerProperties server;

    @Autowired(required = false)
    protected MultipartConfigElement multipartConfig;

    @Value("${project.rest.base-api-path}")
    protected String baseApiPath;

    protected DispatcherServlet createApiModuleDispatcherServlet() {
        AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
        webContext.setParent(applicationContext);
        webContext.register(getApiModuleConfigurationClass());
        return new DispatcherServlet(webContext);
    }

    protected ServletRegistrationBean createApiModuleDispatcherServletRegistration(DispatcherServlet apiModuleDispatcherServlet) {
        ServletRegistrationBean registration = new ServletRegistrationBean(
                apiModuleDispatcherServlet,
                this.server.getServletMapping() + baseApiPath + "/" + getApiModulePath() + "/*");

        registration.setName(getApiModuleDispatcherServletBeanName());
        if (this.multipartConfig != null) {
            registration.setMultipartConfig(this.multipartConfig);
        }
        return registration;
    }

    protected abstract String getApiModuleDispatcherServletBeanName();

    protected abstract String getApiModulePath();

    protected abstract Class<T> getApiModuleConfigurationClass();

}

现在,模块 A 的自动配置类将如下所示:

@Configuration
@ConditionalOnClass(ApiModuleAConfiguration.class)
@ConditionalOnProperty(prefix = "project.moduleA.", value = "enabled")
public class ApiModuleAAutoConfiguration extends AbstractApiModuleAutoConfiguration<ApiModuleAConfiguration> {

    public static final String API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME = "apiModuleADispatcherServlet";
    public static final String API_MODULE_A_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "apiModuleADispatcherServletRegistration";

    @Value("${project.moduleA.path}")
    private String apiModuleAPath;

    @Bean(name = API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME)
    public DispatcherServlet apiModuleADispatcherServlet() {
        return createApiModuleDispatcherServlet();
    }

    @Bean(name = API_MODULE_A_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
    public ServletRegistrationBean apiModuleADispatcherServletRegistration() {
        return createApiModuleDispatcherServletRegistration(apiModuleADispatcherServlet());
    }

    @Override
    protected String getApiModuleDispatcherServletBeanName() {
        return API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME;
    }

    @Override
    protected String getApiModulePath() {
        return apiModuleAPath;
    }

    @Override
    protected Class<ApiModuleAConfiguration> getApiModuleConfigurationClass() {
        return ApiModuleAConfiguration.class;
    }

}

而现在,你的ApiModuleA配置, ApiModuleB配置...配置类将位于每个 api 模块上项目模块 a-api, 项目模块 b-api...

他们可以存储库RestMvcConfiguration或者它们可以从中扩展,或者它们可以是导入 Spring Data REST 配置的任何其他配置类。

最后但并非最不重要的一点是,我在主模块中创建了不同的 gradle 脚本项目服务器根据传递给 gradle 的属性进行加载以模拟 Maven 配置文件。每个脚本都将需要包含的 api 模块声明为依赖项。它看起来像这样:

- project-server
    /profiles/
        profile-X.gradle
        profile-Y.gradle
        profile-Z.gradle

例如,轮廓-X启用 API 模块 A 和 B:

dependencies {
    compile project(':project-module-a-api')
    compile project(':project-module-b-api')
}

processResources {
    from 'src/main/resources/profiles/profile-X'
    include 'profile-x.properties'
    into 'build/resources/main'
}

其他配置文件可以启用不同的 API 模块。

配置文件以这种方式从项目服务器.gradle:

loadProfile()

processResources {
    include '**/*'
    exclude 'profiles'
}

dependencies {
        compile (project(':project-api-autoconfigure')) {
            exclude module: 'project-module-a-api'
            exclude module: 'project-module-b-api'
            ...
        }
        ...
    }

...

def loadProfile() {
    def profile = hasProperty('profile') ? "${profile}" : "dev"
    println "Profile: " + profile
    apply from: "profiles/" + profile + ".gradle"
}

或多或少就是这样。我希望它对你有帮助。

Cheers.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot (JAR),具有多个调度程序 servlet,用于使用 Spring Data REST 的不同 REST API 的相关文章

  • 在 Eclipse 中跨文件搜索注释掉的代码

    有没有一种快速方法可以在 Eclipse 中查找 Java 文件中所有注释掉的代码 也许是搜索中的任何选项 或者任何可以执行此操作的附加组件 它应该只能找到被注释掉的代码 而不是普通的注释 在 Eclipse 中 我只是在打开正则表达式复选
  • 使用 Hibernate 或 Spring 打印 DBMS_OUTPUT.put_line

    我想知道 Hibernate 或 Spring 或任何第 3 方库是否提供将 DBMS OUTPUT put line 消息直接打印到 system out 或日志文件的能力 目的是在控制台中同时显示 PLSQL 日志消息和 java 日志
  • 为什么Java HashMap的最大容量是1<<30而不是1<<31?

    Why is the maximum capacity of a Java HashMap 1 lt lt 30 and not 1 lt lt 31 even though the max value of an int is 231 1
  • 使用 Java 检索 Window 进程的 CPU 使用率

    我正在寻找一个 Java 解决方案来查找 Windows 中正在运行的进程的 CPU 使用情况 查了一下网上 关于Java解决方案的信息似乎很少 请记住 我并不是要查找 JVM 的 CPU 使用情况 而是要查找当时在 Windows 中运行
  • UnsupportedOperationException:特权进程中不允许使用 WebView

    我在用android sharedUserId android uid system 在我的清单中获得一些不可避免的权利 从 HDMI 输入读取安卓盒子 http eweat manufacturer globalsources com s
  • 将位于 jar 中的文件读取为 java.io.File 对象

    与此类似的问题已发布 但似乎没有一个答案对我的情况有帮助 我正在编写一个程序包 它使用 Google 的凭据来获取 Google Apps 用户 为此 我使用服务帐户 因此为了检索凭据 我需要提供 除其他外 一个 p12 签名文件 Cred
  • splitByWholeSeparatorPreserveAllTokens 和 split 之间的区别

    有什么区别StringUtils splitByWholeSeparatorPreserveAllTokens and String split With splitByWholeSeparatorPreserveAllTokens 我们可
  • java“类文件包含错误的类”错误

    我正在尝试制作一个控制台应用程序来测试我的网络服务 我成功部署了一个网络服务http localhost 8080 WS myWS http localhost 8080 WS myWS我用 wsimport 制作了代理类 wsimport
  • java中main的返回类型

    我想知道为什么java中main方法只有void返回类型 public static void main String args 为什么main方法除了void之外没有其他返回类型 Thanks 简短的回答是 因为这就是语言规范 http
  • 当另一个线程发生事情时从主线程获取数据?

    目前我有一个线程正在运行一个侦听连接的套接字 当它收到连接时 它需要上传在主线程中收集的数据 即从主线程获取数据 但是 我传递了对象的实例 但它从未使用等待连接时收集的数据进行更新 有没有正确的方法来做到这一点 我用谷歌搜索了一下 似乎找不
  • 捕获 XSS(跨站脚本)攻击的最佳正则表达式(Java 中)?

    杰夫实际上在净化 HTML http refactormycode com codes 333 sanitize html 但他的示例是用 C 编写的 而我实际上对 Java 版本更感兴趣 有人有更好的 Java 版本吗 他的示例是否足以直
  • 运行 Spring 测试时如何修复 H2 插件(版本 1.4.200)的错误:JdbcSQLSyntaxErrorException:未找到列“start_value”

    我必须将 Spring Boot starter 从 2 1 4 RELEASE 更新到 2 2 6 RELEASE 但现在集成测试失败 我的测试是用 Groovy 进行的 我的应用程序是用 Java 编写的 它们与之前的 Spring 版
  • 我们可以用java定制一个垃圾收集器吗?

    我们知道java的垃圾收集器是一个低优先级线程 在java中我们可以创建任何具有高优先级的线程 那么是否有可能拥有我们自己定制的具有可变优先级的垃圾收集器线程 我们可以根据内存管理的级别进行设置 有人尝试过吗 如果是的话 您能分享一些关于如
  • 从 SQL 语句中检索元数据(表名)

    我使用的是 Visual Studio 2008 我创建了一个 Winforms 应用程序 并且尝试从 SQL 语句中提取表名 con new SqlConnection connString String queryString Sele
  • JTable中动态加载大量数据

    这是我的问题 我目前有一个 JTable 其中包含 5 000 到超过 200 000 行 你知道我要说什么了 数据已经加载到内存中了 这不是问题 但是如何 我可以创建一个高效的 JTable 以便它只加载以下行 是可见的 并且任何事件仅作
  • Web 应用程序似乎启动了名为 [22] 的线程,但未能停止它。这很可能造成内存泄漏

    我有一个 Web 应用程序 后端有 Servlet 部署在 tomcat 上 该应用程序是简单的java应用程序 我经常在服务器日志中看到此错误 严重 Web 应用程序似乎启动了一个名为 22 但未能阻止它 这很有可能 造成内存泄漏 是否存
  • Admob - 没有广告可显示

    你好 我尝试制作一些在 Android 手机上显示广告的示例程序 并尝试在 v2 2 的模拟器上测试它 代码中的一切似乎都很好 但调试器中的 AdListener 表示 响应消息为零或空 onFailedToReceiveAd 没有广告可显
  • 如何手动添加Android Studio依赖

    我多次尝试向我的项目添加依赖项 但每次都会出现错误 我想添加它们的依赖项是 de hdodenhof circleimageview 1 3 0 and com github bumptech glide glide 3 6 1 所以我想下
  • 如何使用 AEM 解析 org.apache.http.ssl?

    最终 我尝试在 Java 代码中使用 AWS S3 库来通过 AEM 启用服务器端 S3 上传 但在安装依赖项和 或由 AEM 识别时遇到了问题 每次我添加新的依赖项时 都会弹出五个问题 在我尝试构建的这个包中 这是我看到的错误 The i
  • Java applet 是否会违反同源策略

    我需要请求一些东西并从其他域获取信息 我知道由于同源政策 javascript 无法做到这一点 我的另一个选择是通过我的服务器发出代理请求 我不希望请求来自我的服务器的 IP 也不想为我的服务器创建额外的负载 并且希望客户端这样做 是否可以

随机推荐

  • 包可见性[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 为什么要使用包可见性 默认 除非该类在 java 中应该是 public 正如 Rostislav Matl 所说 当您想要制作不属于软件包界面一部分的东西时 它非常有用 举个例
  • AffineTransform:从中心缩放形状

    我正在尝试使用 AffineTransform 从中心缩放矩形 我确信解决方案是显而易见的 但我无法使其发挥作用 这是我迄今为止测试过的 import java awt Color import java awt Dimension imp
  • 如何更改 Lollipop 上最新 Chrome 版本中标题栏和地址栏的颜色?

    我还没有找到关于这个主题的任何内容 我真的很喜欢在概览上更改地址栏颜色和标题颜色的功能 是否有捷径可寻 我想你需要安卓5 0 Lollipop 要让它工作 而 Chrome 的合并选项卡和应用程序 set to On 经过一番搜索后我找到了
  • Javascript 字符串对象只读?

    a new String Hello a 0 H true a 0 J a 0 J false a 0 H true 这是否意味着我只能使用字符串作为字符数组 split 进而 join ANSWER 是的 在Javascript stri
  • 使用依赖注入注入依赖注入器

    对于依赖注入来说相当陌生 我试图弄清楚这是否是一种反模式 假设我有 3 个程序集 Foo Shared this has all the interfaces Foo Users references Foo Shared Foo Paym
  • @RefreshScope 不工作 - Spring Boot

    我正在遵循此处描述的方法 https github com jeroenbellen blog manage and reload spring properties 唯一的区别是 就我而言 这些属性在多个类中使用 因此我将它们全部放在一个
  • Facebook 登录建议需要 HTTPS - 如何在 ASP.NET MVC 中为 Facebook 登录配置 HTTP 重定向 URL?

    Facebook 建议我使用 HTTPS 重定向 URL 而不是 HTTP 我一直在尝试找到一种方法来配置它来生成 HTTPS URL 目前它正在生成 HTTP URL http example com signin facebook sc
  • 数组的大小是在编译时确定的吗?

    当我在阅读有关数组初始化的内容时本教程 我发现了这个注释 type name elements 注意 方括号内的元素字段 表示数组中元素的数量 必须是常量表达式 因为数组是静态内存块 其大小必须在程序运行之前的编译时确定 据我所知 数组在运
  • 检查一个字符是否是Java中的特殊字符[重复]

    这个问题在这里已经有答案了 可能的重复 JAVA 检查字符串中是否有特殊字符 我是一名新手程序员 正在寻求帮助确定某个字符是否是特殊字符 我的程序要求用户输入文件名 程序读取文件中的文本并确定文本中有多少个空格 数字 字母和特殊字符 我已完
  • LARAVEL5 自定义登录

    我正在使用需要自定义登录的应用程序 我必须遵循这个流程 用户将进入登录页面 用户提交登录页面 应用程序将检查用户是否在数据库中 3 1 如果用户不在数据库中 会向第三方发送请求 检查是否登录成功 3 2 如果用户在数据库中 则验证密码 现在
  • statsmodel 中的 MNLogit 返回 nan

    我正在尝试在著名的虹膜数据集上使用 statsmodels 的 MNLogit 函数 当我尝试拟合模型时 我得到 当前函数值 nan 这是我正在使用的代码 import statsmodels api as st iris st datas
  • 有没有任何工具可以比较两个网页的结构?

    我从我们的创意团队收到 HTML 页面 然后使用它们构建 aspx 页面 我经常面临的一项挑战是让我输出的 HTML 与他们的完全匹配 我几乎总是把嵌套搞砸 div 位于我的页面和母版页之间 有谁知道在这种情况下有帮助的工具 可以比较两个页
  • 模拟输入上的点击事件 - JavaScript

    我试图通过点击来模拟输入标签的点击anchor标签 这样我可以隐藏输入并将图像包装在锚标签内 这可以使用 jQuery 触发函数来工作 但我不能让它只使用 普通 Javascript jQuery 版本 let fake fake fake
  • C# 中的柯里化表达式

    我正在尝试构建一个可以输入 Linq2SQL 的表达式树 以便它将生成一个漂亮的干净查询 我的目的是构建一个过滤器 将任意单词集与 AND 和 NOT 或 OR 和 NOT 结合在一起 因为我想改变我搜索的字段 所以我最好想组成一个列表Ex
  • 无法在 Mac High Sierra 上打开 UIAutomatorviewer

    我们有配备 High Sierra 10 13 6 的全新 MacBook 其他系统信息 JAVA Version java version 11 0 1 2018 10 16 LTS Java TM SE 运行时环境 18 9 内部版本
  • 在 Android 中创建带有可点击图像的网格视图

    我想创建一个带有可单击图像的网格视图 每当单击图像时 相应的值就会显示在网格视图下方 我面临的问题是在设计部分 我不知道如何设计这样的网格视图 每次我尝试这样做时 都会得到一些不好的结果 我目前还没有 Android UI 设计经验 我怎样
  • 使用 EmptyWorkingSet 有哪些副作用?

    我使用下面的代码来释放某些正在运行的程序的内存 因为我自己的程序需要大量内存资源才能运行得更快 DllImport psapi dll public static extern bool EmptyWorkingSet IntPtr hPr
  • 在 Python 中建模时检测多共线性或具有线性组合的列:LinAlgError

    我正在为具有 34 个因变量的 logit 模型进行数据建模 并且它不断抛出奇异矩阵错误 如下所示 Traceback most recent call last File
  • iowin32.h 中的 OF 宏

    我无法理解 minizip 的 iowin32 h 中的以下行 void fill win32 filefunc OF zlib filefunc def pzlib filefunc def Source 过时但仍然相关 什么是OF宏呢
  • Spring Boot (JAR),具有多个调度程序 servlet,用于使用 Spring Data REST 的不同 REST API

    我有一个项目 它使用 Spring Boot 生成一个可执行 JAR 该 JAR 通过 Spring Data REST 公开 REST API 它还与 Spring Security OAuth 集成 效果很好 我的问题如下 我希望为 R