返回顶部
首页 > 资讯 > 精选 >SpringBoot的jar包怎么启动
  • 732
分享到

SpringBoot的jar包怎么启动

2023-06-29 13:06:19 732人浏览 薄情痞子
摘要

这篇文章主要介绍了SpringBoot的jar包怎么启动,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、简介使用过SprongBoot打过jar包的都应该知道,目标文件一般

这篇文章主要介绍了SpringBootjar包怎么启动,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

    一、简介

    使用过SprongBoot打过jar包的都应该知道,目标文件一般都会生成两个文件,一个是以.jar的包,一个是.jar.original文件。那么使用springBoot会打出两个包,而.jar.original的作用是什么呢?还有就是java -jar是如何将一个SpringBoot项目启动,之间都进行了那些的操作?

    其实.jar.originalMavenSpringBoot重新打包之前的原始jar包,内部只包含了项目的用户类,不包含其他的依赖jar包,生成之后,SpringBoot重新打包之后,最后生成.jar包,内部包含了原始jar包以及其他的引用依赖。以下提及的jar包都是SpringBoot二次加工打的包。

    二、jar包的内部结构

    SpringBoot打出的jar包,可以直接通过解压的方式查看内部的构造。一般情况下有三个目录。

    • BOOT-INF:这个文件夹下有两个文件夹classes用来存放用户类,也就是原始jar.original里的类;还有一个是lib,就是这个原始jar.original引用的依赖。

    • META-INF:这里是通过java -jar启动的入口信息,记录了入口类的位置等信息。

    • org:Springboot loader的代码,通过它来启动。

    这里主要介绍一下/BOOT-INF/MANIFEST.MF文件

    Main-Class: org.springframework.boot.loader.JarLauncherStart-Class: cn.com.springboot.center.AuthEenterBootstrap

    Main-Class:记录了java -jar的启动入口,当使用该命令启动时就会调用这个入口类的main方法,显然可以看出,Springboot转移了启动的入口,不是用户编写的xxx.xxx.BootStrap的那个入口类。

    Start-Class:记录了用户编写的xxx.xxx.BootStrap的那个入口类,当内嵌的jar包加载完成之后,会使用LaunchedURLClassLoader线程加载类来加载这个用户编写的入口类。

    三、加载过程

    1.使用到的一些类

    3.1.1 Archive

    归档文件接口,实现迭代器接口,它有两个子类,一个是JarFileArcHivejar包文件使用,提供了返回这个jar文件对应的url、或者这个jar文件的MANIFEST文件数据信息等操作。是ExplodedArchive是文件目录的使用也有获取这个目录url的方法,以及获取这个目录下的所有Archive文件方法。

    SpringBoot的jar包怎么启动

    3.1.2 Launcher

    启动程序的基类,这边最后是通过JarLauncher#main()来启动。ExecutableArchiveLauncher是抽象类,提供了获取Start-Class类路径的方法,以及是否还有内嵌对应文件的判断方法和获取到内嵌对应文件集合的后置处理方法的抽象,由子类JarLauncherWarLauncher自行实现。

    SpringBoot的jar包怎么启动

    3.1.3 Spring.loader下的JarFile和JarEntry

    jarFile继承于jar.util.jar.JarFileJarEntry继承于java.util.jar.JarEntry,对原始的一些方法进行重写覆盖。每一个JarFileArchive都拥有一个JarFile方法,用于存储这个jar包对应的文件,而每一个JarFile都有一个JarFileEntries,JarFileEntries是一个迭代器。总的来说,在解析jar包时,会将jar包内的文件封装成JarEntry对象后由JarFile对象保存文件列表的迭代器。所以JarFileArchiveJarFileEntries之间是通过JarFile连接,二者都可以获取到JarFile对象。

    2.过程分析

    MANIFEST.MF文件中的Main-class指向入口开始。

    创建JarLauncher并且通过它的launch()方法开始加载jar包内部信息。

    public static void main(String[] args) throws Exception {  new JarLauncher().launch(args);}

    JarLauncher的空构造方法时一个空实现,刚开始看的时候还懵了一下,以为是在后续的操作中去加载的文件,其实不然,在创建时由父类ExecutableArchiveLauncher的构造方法去加载的文件。

    加载为归档文件对象:

    this.archive = createArchive();

    具体的加载方法:判断路径是否是一个文件夹,是则返回ExplodedArchive对象,否则返回JarFileArchive 进入JarFileArchive类:通过这个new方法创建JarFile对象

    public class JarFileArchive implements Archive {  public JarFileArchive(File file, URL url) throws IOException {    this(new JarFile(file));    this.url = url;  }}

    进入到JarFile方法:通过RandoMaccessDataFile读取文件的内容,并传递给本类中的方法进行具体的解析。

    public class JarFile extends java.util.jar.JarFile {  public JarFile(File file) throws IOException {    this(new RandomAccessDataFile(file));  }}

    进入jarLauncherlaunch方法:注册URL协议的处理器,没有指定时,默认指向org.springframework.boot.loader包路径,获取类路径下的归档文件Archive并通过这些归档文件的URL,创建线程上下文类加载器,使用类加载器和用户编写的启动入口类,通过反射调用它的main方法。

    protected void launch(String[] args) throws Exception {  JarFile.reGISterUrlProtocolHandler();  ClassLoader classLoader = createClassLoader(getClassPathArchives());  launch(args, getMainClass(), classLoader);}

    JarLaunchergetClassPathArchives是在ExecutableArchiveLauncher中实现:获取归档文件中满足EntryFilterg过滤器的项,isNestedArchive方法由具体的之类实现。获取到当前归档文件下的所有子归档文件之后的后置操作,是一个扩展点。在JarLauncher中是一个空实现。

    JarLauncher的具体实现,这里通过判断是否在BOOT-INF/lib/包下返回true 也就是说只会把jar包下的BOOT-INF/lib/下的文件加载为Archive对象

    protected boolean isNestedArchive(Archive.Entry entry) {  if (entry.isDirectory()) {    return entry.getName().equals(BOOT_INF_CLASSES);  }  return entry.getName().startsWith(BOOT_INF_LIB);}

    JarFileArchivegetNestedArchives方法:若匹配器匹配到则获取内嵌归档文件。

    具体的获取内嵌归档文件逻辑:根据具体的Entry对象,创建JarFile对象并封装成归档文件对象后返回。

    protected Archive getNestedArchive(Entry entry) throws IOException {    try {        JarFile jarFile = this.jarFile.getNestedJarFile(jarEntry);        return new JarFileArchive(jarFile);    }}

    获取到参数entry对应的RandomAccessData对象,这里根据springboot扩展的url协议,在父路径的基础上添加!/来标记子包。

    private JarFile createJarFileFromFileEntry(JarEntry entry) throws IOException {    RandomAccessData entryData = this.entries.getEntryData(entry.getName());    return new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName(),                       entryData, JarFileType.NESTED_JAR);}

    到这基本上读取jar内部信息,加载为对应归档文件对象的大概过程已经讲完了,接下来分析一下在获取到了整个jar的归档文件对象后的处理。

    通过归档文件对象列表,获取对应的url信息,并通过url信息创建LaunchedURLClassLoader

    protected ClassLoader createClassLoader(List<Archive> archives) {    List<URL> urls = new ArrayList<URL>(archives.size());    for (Archive archive : archives) {        urls.add(archive.getUrl());    }    return createClassLoader(urls.toArray(new URL[urls.size()]));}

    获取到对应的LaunchedUrlClassLoader类加载器之后,设置线程的上下文类加载器为该加载器。根据MANIFI.MF文件中的start-classs信息创建项目启动入口主类对象,并通过返回对象的run方法启动

    protected void launch(String[] args, String mainClass, ClassLoader classLoader) {    Thread.currentThread().setContextClassLoader(classLoader);    createMainMethodRunner(mainClass, args, classLoader).run();}

    进入MainMethodRunnerrun方法:先通过当前线程获取到main入口类,然后通过反射调用启动项目启动类的main方法

    public void run() throws Exception {    Class<?> mainClass = Thread.currentThread().getContextClassLoader()                    .loadClass(this.mainClassName);    Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);    mainMethod.invoke(null, new Object[] { this.args });}

    最后来说一下这个LaunchedURLClassLoader,它继承于URLClassLoader,并重写了loadClass方法

    LaunchedClassLoaderloadClass方法:调用父类loadClass方法,走正常委派流程,最终会被LaunchURLClassLoader加载。

    @Overrideprotected Class<?> loadClass(String name, boolean resolve){   try {      try {         definePackageIfNecessary(name);      }      return super.loadClass(name, resolve);   }}

    进入URLClassLoader中根据springboot解析进行解析。根据名称将路径转化为以.class结尾的/分隔的格式。通过UrlClassPath对象根据路径获取资源类文件

    new PrivilegedExceptionAction<Class<?>>() {    public Class<?> run() throws ClassNotFoundException {      String path = name.replace('.', '/').concat(".class");      Resource res = ucp.getResource(path, false);      if (res != null) {        try {          return defineClass(name, res);        }      }    }  }

    感谢你能够认真阅读完这篇文章,希望小编分享的“SpringBoot的jar包怎么启动”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

    --结束END--

    本文标题: SpringBoot的jar包怎么启动

    本文链接: https://www.lsjlt.com/news/325215.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • SpringBoot的jar包怎么启动
      这篇文章主要介绍了SpringBoot的jar包怎么启动,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、简介使用过SprongBoot打过jar包的都应该知道,目标文件一般...
      99+
      2023-06-29
    • linux怎么启动jar包
      在Linux系统中,可以使用以下命令来启动一个.jar文件: java -jar 文件名.jar 其中,java是启动Java虚拟机...
      99+
      2023-10-25
      linux jar
    • SpringBoot的jar包如何启动的实现
      目录一、简介二、jar包的内部结构三、加载过程1.使用到的一些类2.过程分析四、总结一、简介 ​ 使用过SprongBoot打过jar包的都应该知道,目标文件一般都会生成两个文件,一...
      99+
      2024-04-02
    • SpringBoot为什么可以使用Jar包启动
      这篇文章将为大家详细讲解有关SpringBoot为什么可以使用Jar包启动,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。引言很多初学者会比较困惑,Spring Boot 是如何做到将应用代码和所有的依赖打...
      99+
      2023-06-29
    • Windows 下后台启动 jar 包,UTF-8 启动 jar 包
      目录 1. Windows 下启动 jar 包2. 设置 cmd 编码3. UTF-8 编码启动 jar 包4. 不设置 cmd 编码,utf-8 启动 jar 包 1. Windows ...
      99+
      2023-09-23
      windows jar java
    • SpringBoot应用jar包启动原理详解
      目录1、maven打包2、Jar包目录结构3、可执行Jar(JarLauncher)4、WarLauncher5、总结1、maven打包 Spring Boot项目的pom.xml文...
      99+
      2024-04-02
    • 使用springboot的jar包能够以service方式启动
      目录springboot jar包以service启动场景过程其他SpringBoot启动服务的三种方式1.IDEA启动2.命令行启动3.命令行编译为jar启动springboot ...
      99+
      2024-04-02
    • SpringBoot为何可以使用Jar包启动详解
      目录引言Spring Boot 打包插件SpringBoot FatJar 的组织结构MAINFEST.MF 元信息启动原理源码分析JarLauncherLauncherProper...
      99+
      2024-04-02
    • springboot项目(jar包)指定配置文件启动
      IDE开发工具启动 在JetBrains IDEA开发工具的配置 1.启动类启动方式 2.main方法启动方式 在IDEA中的program arguments配置此项--spring.profiles.active=dev命令 3....
      99+
      2023-08-20
      spring boot jar java
    • nohup启动jar包详解
      nohup解释: nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。 &解释: & 代表后台运行 命令结尾没有 “&” ,则变成 “j...
      99+
      2023-09-07
      jar java spring
    • SpringBoot怎么打jar包与war包
      这篇文章主要介绍“SpringBoot怎么打jar包与war包”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot怎么打jar包与war包”文章能帮助大家解决问题。一. SpringB...
      99+
      2023-07-05
    • Linux启动jar包的shell脚本
      背景: 项目设备端需要运行jar包程序与服务端进行socket连接并发送数据,每次启动进程时,都需要在linux终端输入启动jar包的命令,比较繁琐,随之尝试将启动jar包的命令写入shell脚本文件中,实现操作shel...
      99+
      2022-06-04
      shell脚本启动jar包 linux shell启动jar包
    • Linux编辑启动、停止与重启springboot jar包脚本实例
      前言 springboot的配置文件中,配置文件的名字都有各自的意义跟用途 dev 开发环境 prod 生产环境(默认) test 测试环境 加载指定配置文件 --spring.profiles.acti...
      99+
      2022-06-04
      linux启动停止重启 jar包脚本
    • 指定jdk启动jar包的方法
      在做一个modbus协议数据解析小项目时,碰到JDK版本过低问题。在进行项目启动时,指定jdk版本,解决了服务器多jdk问题。 一、windows版本下项目启动 1、编写一个run.bat文件,具...
      99+
      2023-09-02
      java jar 服务器
    • jar包的启动方式有哪些
      本文小编为大家详细介绍“jar包的启动方式有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“jar包的启动方式有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、各种启动方式1.java -jar#&nb...
      99+
      2023-07-05
    • Springboot怎么打包成jar发布
      这篇“Springboot怎么打包成jar发布”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Springboot怎么打包成j...
      99+
      2023-07-05
    • java -jar启动的五种方式(包括后台启动)
      用java -jar xxx.jar 点击回车就会启动成功,但是当退出或者关闭远程工具就会把进程关闭 java -jar xxx.jar 以上就是启动的项目Java -jar xxx.jar 但是点击过Ctl+c或者把此窗口关闭 就会杀死进...
      99+
      2023-08-16
      java jar linux
    • tomcat如何启动jar包项目
      要在Tomcat上启动一个包含jar包的项目,需要将jar包添加到项目的类路径中,并将项目部署到Tomcat的webapps目录中。...
      99+
      2024-04-02
    • Linux中jar包启动和jar包后台运行的实现方式
      linux 运行jar包命令如下: 方式一: java -jar shareniu.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 java ...
      99+
      2022-06-04
      linux jar包启动 linux jar包
    • SpringBoot项目(jar)部署,启动脚本
      需求 SpringBoot项目(jar)部署,需要先关闭原来启动的项目,再启动新的项目。直接输入命令,费时费力,还容易出错。所以,使用脚本启动。 脚本 脚本名:start.sh 此脚本需要放置在jar包的同级目录,才能正确找到jar包。 #...
      99+
      2023-08-30
      spring boot jar linux bash
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作