快速做网站公司报价,如何做天猫网站,龙轩导航,榆林网站优化Spring Boot 提供了一个插件 spring-boot-maven-plugin 把程序打包成一个可执行的jar包#xff0c;直接执行java -jar xxx.jar即可以启动程序
1、引用 spring-boot-maven-plugin插件
buildpluginsplugingroupIdorg.springframework.boot直接执行java -jar xxx.jar即可以启动程序
1、引用 spring-boot-maven-plugin插件
buildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins
/build
2、打包文件内部结构 1、BOOT-INF class项目代码 lib依赖jar包 2、META-INF程序入口 maven.xxx程序配置文件 MANIFEST.MF 3、org.springframework.boot.loader
3、MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: sk-cloud-order-sc
Implementation-Version: 1.0-SNAPSHOT
Start-Class: com.sk.order.sc.app
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 1.4.3.RELEASE
Created-By: Maven JAR Plugin 3.2.2
Main-Class: org.springframework.boot.loader.JarLauncher Main-Classorg.springframework.boot.loader.JarLauncher当我们使用java -jar xxx.jar启动jar包的时候通过调用JarLauncher#Main方法不是我们定义的Main方法。SpringBoot内部提供一个可用于执行SpringBootApplication的工具类这就是为什么打的包包含spring-boot-loader 4、JarLauncher源码查看 1、添加依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-loader/artifactIdversion2.7.8/version
/dependency 2)、抽象Launcher类 用于启动应用程序分别有JarLauncher、WarLauncher、PropertiesLauncher实现类
public abstract class Launcher {private static final String JAR_MODE_LAUNCHER org.springframework.boot.loader.jarmode.JarModeLauncher;public Launcher() {}protected void launch(String[] args) throws Exception {if (!this.isExploded()) {JarFile.registerUrlProtocolHandler();}ClassLoader classLoader this.createClassLoader(this.getClassPathArchivesIterator());String jarMode System.getProperty(jarmode);String launchClass jarMode ! null !jarMode.isEmpty() ? org.springframework.boot.loader.jarmode.JarModeLauncher : this.getMainClass();this.launch(args, launchClass, classLoader);}protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {Thread.currentThread().setContextClassLoader(classLoader);this.createMainMethodRunner(launchClass, args, classLoader).run();}//Archive相关代码
} 3、Archive归档文件获取Mainifest等URL路径jar包中包含jar或者jar包中class文件那么会使用 !/ 分隔开
public class JarFileArchive implements Archive {public URL getUrl() throws MalformedURLException {return this.url ! null ? this.url : this.jarFile.getUrl();}public Manifest getManifest() throws IOException {return this.jarFile.getManifest();}
}
4、JarFilejar包封装文件 5、JarLauncher启动流程 JarLauncher#main - Launcher#launch -MainMethodRunner#run -获取manifest文件Start-Class类通过反射调用main方法 public class JarLauncher extends ExecutableArchiveLauncher {static final Archive.EntryFilter NESTED_ARCHIVE_ENTRY_FILTER (entry) - {return entry.isDirectory() ? entry.getName().equals(BOOT-INF/classes/) : entry.getName().startsWith(BOOT-INF/lib/);};public JarLauncher() {}protected JarLauncher(Archive archive) {super(archive);}protected boolean isPostProcessingClassPathArchives() {return false;}protected boolean isNestedArchive(Archive.Entry entry) {return NESTED_ARCHIVE_ENTRY_FILTER.matches(entry);}protected String getArchiveEntryPathPrefix() {return BOOT-INF/;}public static void main(String[] args) throws Exception {(new JarLauncher()).launch(args);}
} Launcher#launch protected void launch(String[] args) throws Exception {if (!this.isExploded()) {JarFile.registerUrlProtocolHandler();}//自定义类加载器加载jar文件通过active的urls加载jar文件ClassLoader classLoader this.createClassLoader(this.getClassPathArchivesIterator());String jarMode System.getProperty(jarmode);//获取manifest文件的Start-Class类String launchClass jarMode ! null !jarMode.isEmpty() ? org.springframework.boot.loader.jarmode.JarModeLauncher : this.getMainClass();//调用Start-Class类类main方法this.launch(args, launchClass, classLoader);
}protected void launch(String[] args, String launchClass, ClassLoader classLoader) throws Exception {Thread.currentThread().setContextClassLoader(classLoader);this.createMainMethodRunner(launchClass, args, classLoader).run();
}/*
* 调用manifest文件Start-Class类mian方法
*/
public class MainMethodRunner {private final String mainClassName;private final String[] args;public MainMethodRunner(String mainClass, String[] args) {this.mainClassName mainClass;this.args args ! null ? (String[])args.clone() : null;}public void run() throws Exception {Class? mainClass Class.forName(this.mainClassName, false, Thread.currentThread().getContextClassLoader());Method mainMethod mainClass.getDeclaredMethod(main, String[].class);mainMethod.setAccessible(true);mainMethod.invoke((Object)null, this.args);}
}