问题描述
我正在学习Spring Boot.我做了一个简单的Spring Boot项目,该项目可以在 http://localhost:8080/welcome 上输出一个hello world字符串.
I am learning Spring Boot. I made a simple Spring Boot project that can output a hello world string at http://localhost:8080/welcome
我使用Maven构建将输出jar文件的项目.要启动我的spring boot应用程序,请使用以下命令
I use Maven to build my project that would output a jar file.To start up my spring boot app, I use the command as below
java -jar my-springboot-app.jar
我的问题是:
java如何足够智能地定位我的主类及其主要方法(例如,应用程序启动器)?
How is java smart enough to locate my main class and its main method (e.g. the application launcher)?
我检查了jar文件并浏览了那些BOOT-INF& META-INF,找不到任何线索.
I checked the jar file and browsed those BOOT-INF & META-INF and could not find any clues.
spring boot框架(@SpringBootApplication)或maven自动为我做魔术吗?
Does the spring boot framework (@SpringBootApplication) or maven automatically do the magic for me?
推荐答案
在使用Spring Boot jar的情况下,事情要比常规jar更复杂.主要是因为spring boot applicaton jar并不是真正的JAR(通过jar,我指的是具有清单和编译类的东西).常规JAR可以由jvm进行识别"并进行处理,但是在Spring Boot中也存在打包的依赖项(请参见BOOT-INF/lib
),因此其JAR内的jars.怎么读?
In case of spring boot jar the things are little bit more complicated than regular jar. Mainly because spring boot applicaton jar is not really a JAR (by jar I mean something that has manifest and compiled classes). Regular JARs can be "recognized" and processed by jvm, however in Spring Boot there are also packed dependencies (take a look at BOOT-INF/lib
) so its jars inside JARs. How to read this?
事实证明,Spring Boot始终具有其自己的主类,该主类确实在MANIFEST.MF中被引用,并且这是打包应用程序的真正入口点.
It turns out that spring boot always has its own main class that is indeed referred to in MANIFEST.MF and this a real entry point of the packaged application.
清单文件包含以下几行:
The manifest file contains the following lines:
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication
Main-Class
是JVM入口点.这个类由spring开发人员编写,基本上有两件事: -建立特殊的类加载器,以处理Spring Boot应用程序的非常规jar"性质.由于这种特殊的类加载器,因此可以处理在BOOT-INF/lib
中包含罐子"的spring boot应用程序,例如,常规的Java类加载器显然不能执行此操作. -调用Start-Class
值的主要方法. Start-Class
是Spring Boot应用程序所独有的东西,它表示包含"main"方法的类-您编写的类以及您认为是入口点的类:)但是从Spring Boot的角度来看基础设施只是一个具有普通"主方法的类-可以通过反射调用的方法.
Main-Class
is a JVM entry point. This class, written by spring developers, basically does two things: - Establishes a special class loader to deal with a "non-regular-jar" nature of spring boot application. Due to this special class loaders spring boot application that contains "jars" in BOOT-INF/lib
can be processed, for example, regular java class loaders apparently cannot do this. - Calls the main method of Start-Class
value. The Start-Class
is a something unique to spring boot applications and it denotes the class that contains a "main" method - the class you write and the class you think is an entry point :) But from the point of view of the spring boot infrastructure its just a class that has an "ordinary" main method - a method that can be called by reflection.
现在有关谁制造清单"的问题:
Now regarding the question "who builds the manifest":
这个MANIFEST.MF通常是由Spring Developers为诸如Maven或Gradle之类的构建系统提供的插件自动创建的.
This MANIFEST.MF is usually created automatically by plugins offered by Spring Developers for build systems like Maven or Gradle.
例如,该插件如下所示:
For example, the plugin looks like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
在工作期间,此插件标识您的主类(在我的示例中为com.example.demo.DemoApplication
).此类用@SpringBootApplication
批注标记,并具有public static void main
方法.但是,如果您放置许多这样的类,则插件可能无法识别正确的类,因此您需要在POM.xml中配置插件属性以指定正确的类.
During its work, this plugin identifies your main class (com.example.demo.DemoApplication
in my example). This class is marked with @SpringBootApplication
annotation and has a public static void main
method.However, if you put many classes like this the plugin probably won't recognize the correct class so you'll need to configure the plugin properties in POM.xml to specify the right class.
这篇关于Java运行时如何找到我的主类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!