Analysis of the Spring-Boot-load module in spring boot,
I. Preface
Under normal circumstances, classloader can only find the *. class file in the current directory or file class in jar. Before loading resources in the nested jar, the class files in the nested jar and the class files of the application are packaged as a jar, so that no nested jar exists, however, in this case, you cannot clearly know what the application depends on and which are the application's own. In other jar files, the class content may be different, but the file name may be the same. Spring-boot-loader in springboot was born to solve this problem elegantly.
The spring-boot-loader module allows us to use java-jar archive. jar runs a jar or war file containing nested dependent jar files. It provides three types of starters (JarLauncher, WarLauncher and PropertiesLauncher ), these class starters are designed to load resources nested in jar (such as class files and configuration files ). [Jar | War] Launcher always searches for resources in the nested jar files in the lib directory of the current jar.
Ii. jar directory structure provided by the spring-boot-loader Module
The jar file format in Springboot is fixed as follows:
archive.jar | +-META-INF(1) | +-MANIFEST.MF +-org(2) | +-springframework | +-boot | +-loader | +-<spring boot loader classes> +-com(3) | +-mycompany | + project | +-YouClasses.class +-lib(4) +-dependency1.jar +-dependency2.jar
- Structure (1) storage location of the MANIFEST. MF file in the jar file
- Structure (2) class placement required by Spring-boot-loader
- Structure (3) Application file placement
- Structure (4) the jar files that the application depends on are fixed to the lib directory.
So how does spring-boot Load resources according to this structure?
- First, we will use the spring-boot-maven-plugin plug-in to rewrite the packaged jar file, will set the META-INF/MANIFEST. MF
Main-Class: org.springframework.boot.loader.JarLauncher Start-Class: com.mycompany.project.MyApplication
Copy the class file in the spring-boot-loader package to the structure (2), and copy the application dependency to (4) copy the application class to (3)
- Use java-jar archive. during jar running, Launcher will load the JarLauncher class and execute the main function. JarLauncher mainly focuses on constructing a suitable URLClassLoader loader to call the main method of our application (MyApplication.
Iii. Analysis of the packaging process of spring-boot-maven-plugin plug-in
Note: here we need to think about why to copy the class that should have been put into the spring-boot-loader.jar in lib to the structure (2 )?
Iv. JarLauncher Execution Process Analysis
After reading this process in the analysis of the issues left in Section 3, such as the flowchart first use Appclassloader to load the JarLauncher class and create the LaunchedURLClassLoader class, And LaunchedURLClassLoader is in the spring-boot-loader.jar package, while Appclassloader is a common loader can not load embedded jar files, so if you put the spring-boot-loader.jar to the lib directory, Appclassloader will not find LaunchedURLClassLoader. Therefore, during packaging
Copy the class that should have been put into the spring-boot-loader.jar inside lib to the structure (2 ).
V. Summary
The spring-boot-load module elegantly loads nested jar resources by using the custom jar package structure custom class loader, and re-sets the startup class and the jar structure during packaging, you can set a custom Loader during runtime to load nested jar resources.