Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to start the jar package of SpringBoot

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the SpringBoot jar package how to start, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor take you to know about it.

I. brief introduction

Anyone who has used SprongBoot to package jar should know that the target file usually generates two files, one is a .jar package, and the other is a .jar.original file. So using SpringBoot will type out two packages, but what is the purpose of .jar.original? And how does java-jar start a SpringBoot project and do that in between?

In fact, .jar.original is the original jar package of maven before SpringBoot repackaging, which contains only the user class of the project, not other dependent jar packages. After generation, after SpringBoot repackaging, the .jar package is finally generated, which contains the original jar package and other reference dependencies. The jar packages mentioned below are all packed by SpringBoot secondary processing.

Second, the internal structure of jar packet

For the jar package printed by SpringBoot, you can view the internal structure directly by decompressing it. There are usually three directories.

BOOT-INF: there are two folders under this folder, classes, for storing user classes, the classes in the original jar.original, and lib, which is the dependency of the original jar.original reference.

META-INF: here is the entry information started through java-jar, recording the location of the entry class and other information.

Org:Springboot loader code, through which to start.

Here is a brief introduction to the / BOOT-INF/MANIFEST.MF file

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

Main-Class: the startup entry of java-jar is recorded, and the main method of this entry class is called when starting with this command. It is obvious that Springboot has transferred the startup entry, not the user-written entry class of xxx.xxx.BootStrap.

Start-Class: the entry class that records the user-written xxx.xxx.BootStrap. When the embedded jar package is loaded, the user-written entry class is loaded using the launchedURLClassLoader thread load class.

Third, loading process 1. Some of the classes used

3.1.1 Archive

The archive file interface, which implements the iterator interface, has two subclasses, one is the use of JarFileArchive for jar package files, and provides operations such as returning the url corresponding to the jar file or the MANIFEST file data information of the jar file. ExplodedArchive is the use of the file directory and there is also a way to get the url of this directory, as well as the method of getting all the Archive files in this directory.

3.1.2 Launcher

The base class of the startup program, which is finally started through JarLauncher#main (). ExecutableArchiveLauncher is an abstract class, which provides the method of obtaining the Start-Class classpath, the judgment method of whether there are embedded corresponding files, and the abstraction of the post-processing method of obtaining the embedded corresponding file collection, which is implemented by the subclasses JarLauncher and WarLauncher.

3.1.3 JarFile and JarEntry under Spring.loader

JarFile inherits from jar.util.jar.JarFile,JarEntry and inherits from java.util.jar.JarEntry, overriding some of the original methods. Each JarFileArchive has a JarFile method to store the files corresponding to the jar package, and each JarFile has a JarFileEntries,JarFileEntries that is an iterator. In general, when parsing the jar package, the files in the jar package are encapsulated into JarEntry objects, and the JarFile object saves the iterator of the file list. So the connection between JarFileArchive and JarFileEntries is through JarFile, and both can get the JarFile object.

two。 Process analysis

Start with the Main-class pointing to the entry in the MANIFEST.MF file.

Create a JarLauncher and start loading the jar package internal information through its launch () method.

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

The empty constructor of JarLauncher is an empty implementation, and I was confused at the beginning, thinking that it was a file to be loaded in the subsequent operation, but it was not the file that was loaded by the constructor of the parent class ExecutableArchiveLauncher when it was created.

Load as an archive file object:

This.archive = createArchive ()

Specific loading method: determine whether the path is a folder, and return an ExplodedArchive object, otherwise return JarFileArchive to enter the JarFileArchive class: create a JarFile object through this new method

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

Go to the JarFile method: read the contents of the file through RandomAccessDataFile and pass it to the methods in this class for specific parsing.

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

Enter the launch method of jarLauncher: register the processor of URL protocol. If it is not specified, it points to the org.springframework.boot.loader package path by default, obtains the archive file Archive under the classpath, and creates a thread context classloader through the URL of these archived files. It uses the classloader and the user-written startup entry class to call its main method through reflection.

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

JarLauncher's getClassPathArchives is implemented in ExecutableArchiveLauncher: get the items in the archive file that satisfy the EntryFilterg filter, and the isNestedArchive method is implemented by concrete things like that. The post operation after getting all the sub-archive files under the current archive file is an extension point. Is an empty implementation in JarLauncher.

The specific implementation of JarLauncher. Here, by judging whether true is returned under the BOOT-INF/lib/ package, that is, only the files under the BOOT-INF/lib/ under the jar package will be loaded as Archive objects.

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

The getNestedArchives method of JarFileArchive: get the embedded archive file if the matcher matches.

Specific acquisition embedded archive file logic: according to the specific Entry object, create a JarFile object and encapsulate it into an archive file object and return it.

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

Get the RandomAccessData object corresponding to the parameter entry. Here, according to the url protocol extended by springboot, the child package is marked by adding! / to the parent path.

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);}

At this point, the general process of reading the internal information of jar and loading it as the corresponding archive file object is over. Let's analyze the processing after obtaining the archive file object of the entire jar.

Obtain the corresponding url information by archiving the list of file objects, and create a LaunchedURLClassLoader through the url information

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

After getting the corresponding LaunchedUrlClassLoader classloader, set the thread's context classloader to the loader. Create a project startup entry main class object based on the start-classs information in the MANIFI.MF file, and start it by returning the object's run method

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

Enter the run method of MainMethodRunner: first get the main entry class through the current thread, and then call the main method of the startup class of the startup project through reflection

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});}

Finally, let's talk about this LaunchedURLClassLoader, which inherits from URLClassLoader and overrides the loadClass method.

LoadClass method of LaunchedClassLoader: call the parent class loadClass method, follow the normal delegation process, and will eventually be loaded by LaunchURLClassLoader.

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

Enter the URLClassLoader to parse according to the springboot resolution. Converts the path to a /-delimited format that ends in .class based on the name. Get the resource class file according to the path through the UrlClassPath object

New PrivilegedExceptionAction run () throws ClassNotFoundException {String path = name.replace ('.','/'). Concat (".class"); Resource res = ucp.getResource (path, false); if (res! = null) {try {return defineClass (name, res) Thank you for reading this article carefully. I hope the article "how to start the jar package of SpringBoot" shared by the editor will be helpful to you. At the same time, I also hope you will support us and follow the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report