【问题标题】:Spring Boot - How to specify an alternate start-class? (Multiple Entry Points)Spring Boot - 如何指定备用启动类? (多个入口点)
【发布时间】:2015-09-13 15:04:14
【问题描述】:

我想为我的 Spring-Boot 应用程序添加一个备用入口点。我宁愿把它当作一个肥罐。这可能吗?

根据他们的documentation,属性loader.main指定要启动的主类的名称。

我尝试了java -jar MyJar.jar --loader.main=com.mycompany.AlternateMain,但我的 pom.xml 中指定的 start-class 仍在运行(如果我从 pom.xml 中删除它,那么我会在打包过程中出错)。

或者,我尝试了java -cp MyJar.jar com.mycompany.AlternateMain,但我不知道将所有嵌套 jar 添加到类路径的好方法。

有什么建议吗?

编辑:这是我使用的解决方案

按照 jst 的建议,我将启动器更改为使用 PropertiesLauncher。我通过修改我的 spring-boot-maven-plugin 的配置来做到这一点。

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <mainClass>${start-class}</mainClass>
    <layout>ZIP</layout>
    ...

&lt;layout&gt;ZIP&lt;/layout&gt;triggers Spring Boot to use the PropertiesLauncher

我创建了我的 fat jar(mvn 包),然后像这样调用了备用 main:

java -jar -Dloader.main=com.mycompany.AlternateMain MyJar.jar

感谢您的帮助!

【问题讨论】:

  • Spring Boot 只是使用 JAR 的 Manifest 来指定主类和类路径。所以我认为这里真正的问题是可执行 JAR 中是否可以有多个主类?这个问题也在这里问/回答:stackoverflow.com/q/3976514/953327
  • 你打算用这个完成什么?你想在 Spring Boot 中创建多个应用程序吗?
  • @FGreg 我可以使用我记下的第二个命令访问备用主命令,该命令与您链接到的 SO 线程中的答案相匹配。为了成功使用它,我必须弄清楚如何将嵌套的 jar 添加到类路径中。
  • @Makoto 我不想用这个创建多个应用程序。这实际上是我现在正在做的概念验证,但我过去出于各种原因使用了多个入口点

标签: java spring jar spring-boot


【解决方案1】:

我建议使用单个 main,但使用 Spring 配置文件(或配置属性)来选择一个或其他“入口点”@Configuration 类。

【讨论】:

  • 你能举个例子吗?
【解决方案2】:

我认为该属性不适用于您的情况。有 3 种不同的“启动器”(返回文档并查看)。如果您正在构建一个 jar,它使用 JarLauncher 类。如果将其切换到 PropertiesLauncher,那么 loader.main 会很有用。

META-INF/MANIFEST.MF

Main-Class: org.springframework.boot.loader.PropertiesLauncher

【讨论】:

  • 这听起来很有希望,但我的结果是一样的。为了使用 PropertiesLauncher,我配置了 spring-boot-maven-plugin,如stackoverflow.com/a/21328440/2860319 所述。我可以在我的清单中看到它可以工作并且现在正在使用 PropertiesLauncher,但是通过命令行指定的 loader.main 属性并没有改变 start-class...hmmmm
  • 我添加的属性不正确,我会用我所做的更新我的帖子。谢谢你的好建议!
【解决方案3】:

我采用了不同的方法并使用命令行参数来确定将哪个类用作我的 SpringApplication 类。我只有一个 main() 方法,但是基于命令行参数使用的具有不同配置的不同应用程序类。

我有一个包含 main() 的类:

public static void main(String[] args) {
    SpringApplication app;
    if( ArrayUtils.contains(args, "--createdb")){
        app = new SpringApplication(CreateDB.class);
        args = (String[])ArrayUtils.add(args, "--spring.jpa.hibernate.ddl-auto=create");
    } else {
        app = new SpringApplication(Application.class);
    }

    app.setWebEnvironment(false);
    app.setShowBanner(false);
    app.addListeners(new ConfigurationLogger());

    // launch the app
    ConfigurableApplicationContext context = app.run(args);

    // finished so close the context
    context.close();
}

但我有 2 个不同的 SpringApplication 类:Application.class 和 CreateDB.class。每个类定义不同的@ComponentScan 路径以及不同的@EnableAutoConfiguration 选项和不同的@Configuration 选项。最后,根据我的命令行参数,我可以决定是否以编程方式启用其他配置文件/等。

就我而言,我想要一个不同的启动器来创建数据库架构并退出,所以我强制使用命令行参数。

【讨论】:

  • 这也是我要去的地方,大概CreateDBApplication 存在于单独的包中,因此您可以使用@ComponentScanbasePackages 设置为该包?
  • 确实有可能。就我而言,它们实际上在同一个包中,但我的 @ComponentScan() 明确设置了不同的基本包以使用不同的排除规则进行扫描。它还允许您拥有不同的@AutoConfiguration() 选项、不同的 Config 类等。坦率地说 - 我发现这样做比使用启动器和启动器参数指定长类名称要容易得多;这允许我以任何我想要的方式抽象它。我基本上已经在同一个 jar 中打包了 2 个独立的 SpringBoot 应用程序(它们共享公共类)。
猜你喜欢
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 2020-03-21
  • 1970-01-01
  • 2019-01-23
  • 2018-04-27
相关资源
最近更新 更多