为了账号安全,请及时绑定邮箱和手机立即绑定

Java 运行时如何找到我的主类?

Java 运行时如何找到我的主类?

慕哥9229398 2023-02-23 15:45:51
我正在学习 Spring Boot。我做了一个简单的 Spring Boot 项目,可以在http://localhost:8080/welcome输出一个 hello world 字符串我使用 Maven 构建我的项目,该项目将输出一个 jar 文件。要启动我的 spring boot 应用程序,我使用如下命令java -jar my-springboot-app.jar我的问题是:Java 是如何智能到足以定位我的主类及其主要方法(例如应用程序启动器)的?我检查了 jar 文件并浏览了那些 BOOT-INF 和 META-INF,但找不到任何线索。spring boot 框架 (@SpringBootApplication) 或 maven 会自动为我施展魔法吗?
查看完整描述

2 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

在 spring boot jar 的情况下,事情比普通 jar 复杂一点。主要是因为 spring boot applicaton jar 并不是真正的 JAR(我所说的 jar 是指具有清单和编译类的东西)。常规 JAR 可以被 jvm“识别”和处理,但是在 Spring Boot 中也有打包的依赖项(看一看BOOT-INF/lib),因此它的 jars 在 JAR 中。如何阅读这个?


事实证明,spring boot 总是有自己的主类,它确实在 MANIFEST.MF 中被引用,这是打包应用程序的真正入口点。


清单文件包含以下几行:


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

Start-Class: com.example.demo.DemoApplication

Main-Class是 JVM 入口点。这个由 spring 开发人员编写的类基本上做了两件事: - 建立一个特殊的类加载器来处理 spring boot 应用程序的“非常规 jar”特性。由于这种特殊的类加载器,BOOT-INF/lib可以处理包含“jars”的 spring boot 应用程序,例如,常规的 java 类加载器显然不能这样做。- 调用main方法的Start-Class值。这Start-Class是 spring boot 应用程序独有的东西,它表示包含“main”方法的类 - 您编写的类和您认为是入口点的类 :) 但从 spring boot 基础设施的角度来看,它只是具有“普通”主要方法的类 - 可以通过反射调用的方法。


现在关于“谁构建清单”的问题:


此 MANIFEST.MF 通常由 Spring 开发人员为 Maven 或 Gradle 等构建系统提供的插件自动创建。


例如,插件看起来像这样:


<plugin>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

在其工作期间,此插件会标识您的主类(com.example.demo.DemoApplication在我的示例中)。这个类用@SpringBootApplication注释标记并且有一个public static void main方法。但是,如果您放置许多这样的类,插件可能无法识别正确的类,因此您需要在 POM.xml 中配置插件属性以指定正确的类。


查看完整回答
反对 回复 2023-02-23
?
达令说

TA贡献1821条经验 获得超6个赞

Java 类在更大的上下文中执行,您运行 java -jar somejar.jar将在 .jar 文件的清单中选择有问题的类

@SpringBootApplication 将有componentscan,启用自动配置(autowired)

componentscan - 识别包中的所有控制器、服务和配置类。


查看完整回答
反对 回复 2023-02-23
  • 2 回答
  • 0 关注
  • 138 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信