SpringBoot 2.0 系列002

Stella981
• 阅读 420

SpringBoot 2.0 系列002 --运行流程分析

SpringBoot 2.0 系列001 -- 入门介绍以及相关概念

1. SpringBoot运行的几种方式

1.1 开发环境,右键配置类main方法运行

配置如下,引入相关pom依赖,运行main方法即可启动简单的SpringBoot web应用。

//开启SpringBoot自动注入配置 等价于原来的SpringBootApplication @EnableAutoConfiguration //开启RestController注解 含有ResponseBody 即非页面形式 @RestController public class SpringBootApplication {

@GetMapping("/")
public String home() {
    return "Hello World!";
}

/\*\*
 \* 开启SpringBoot服务
 \* @param args
 \*/
public static void main(String\[\] args) {
    //等价于 new SpringApplication(SpringBootApplication.class).run(args);
    SpringApplication.run(SpringBootApplication.class,args);
}

}

1.2 jar文件运行

其他部分与上述相同,需要注意的是pom文件需要加入

org.springframework.boot spring-boot-maven-plugin

打包方式选择为jar

jar

最后mvn package打包 ,idea里面如下

SpringBoot 2.0 系列002

运行方式1,如下

SpringBoot 2.0 系列002

运行方式2,如下

D:\work\ideawork\SpringBootLearn\chapter02\target>java -jar chapter02-2.0.1.RELEASE.jar

. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.1.RELEASE)

2018-05-11 09:42:52.870 INFO 9720 --- [ main] com.ricky.SpringBootApplication : Starting SpringBootApplication v2.0.1.RELEASE on jsb-bgt with PID 9720 (D:\work\ideawork\SpringBootLearn\chapter02\target\chapter02-2.0.1.RELEASE.jar started by zdwljs in D:\work\ideawork\SpringBootLearn\chapter02\target) 2018-05-11 09:42:52.877 INFO 9720 --- [ main] com.ricky.SpringBootApplication : No active profile set, falling back to default profiles: default 2018-05-11 09:42:52.979 INFO 9720 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5f8ed237: startup date [Fri May 11 09:42:52 CST 2018]; root of context hierarchy 2018-05-11 09:42:55.596 INFO 9720 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2018-05-11 09:43:01.810 INFO 9720 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2018-05-11 09:43:01.811 INFO 9720 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.29 2018-05-11 09:43:01.827 INFO 9720 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\Program Files\Java\jdk1.8.0_161\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;d:\work\Git\cmd;C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Users\zdwljs\AppData\Local\Microsoft\WindowsApps;D:\Program Files\Java\jdk1.8.0_161\bin;;.] 2018-05-11 09:43:01.988 INFO 9720 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2018-05-11 09:43:01.991 INFO 9720 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 9018 ms 2018-05-11 09:43:02.238 INFO 9720 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2018-05-11 09:43:02.263 INFO 9720 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2018-05-11 09:43:02.264 INFO 9720 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2018-05-11 09:43:02.267 INFO 9720 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2018-05-11 09:43:02.271 INFO 9720 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2018-05-11 09:43:02.437 INFO 9720 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-11 09:43:02.877 INFO 9720 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5f8ed237: startup date [Fri May 11 09:42:52 CST 2018]; root of context hierarchy 2018-05-11 09:43:03.069 INFO 9720 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[GET]}" onto public java.lang.String com.ricky.SpringBootApplication.home() 2018-05-11 09:43:03.079 INFO 9720 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2018-05-11 09:43:03.083 INFO 9720 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2018-05-11 09:43:03.139 INFO 9720 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-11 09:43:03.140 INFO 9720 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-05-11 09:43:03.386 INFO 9720 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-05-11 09:43:03.457 INFO 9720 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2018-05-11 09:43:03.466 INFO 9720 --- [ main] com.ricky.SpringBootApplication : Started SpringBootApplication in 11.232 seconds (JVM running for 11.882)

通过ctrl-c可以退出

1.3 war包方式

1.3.1 war形式基本是使用外部tomcat,则需要将内置tomcat依赖过滤掉,且需要添加开发servlet依赖。

org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat javax.servlet javax.servlet-api 3.1.0 provided

1.3.2 注意将打包方式改为war形式

war

1.3.3 两种加载方式

  • 需要配置启动类 ,如下

继承SpringBootServletInitializer,重写configure方法。

//开启SpringBoot自动注入配置 等价于原来的SpringBootApplication @EnableAutoConfiguration //开启RestController注解 含有ResponseBody 即非页面形式 @RestController public class SpringBootApplicationServletInitializer extends SpringBootServletInitializer{

@GetMapping("/")
public String home(HttpServletRequest request) {
    return "Hello World!";
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(SpringBootApplicationServletInitializer.class);
}

}

  • 另一种则是不需要继承SpringBootServletInitializer。保持与jar文件方式一致即可。 虽然也可以正常访问。但是application.yml中的配置不生效。需要通过其他方式进行参数配置。

1.3.3 打包运行

  • 1、 mvn package打包,生成chapter02-2.0.1.RELEASE.war 文件。

  • 2、将war文件放到webapp目录下 SpringBoot 2.0 系列002

  • 3、启动tomcat。(注意:测试发现是没有spring的日志,但是访问正常)

11-May-2018 11:53:34.687 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.29 11-May-2018 11:53:34.694 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Mar 5 2018 13:11:12 UTC 11-May-2018 11:53:34.697 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 8.5.29.0 11-May-2018 11:53:34.698 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Windows 10 11-May-2018 11:53:34.698 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 10.0 11-May-2018 11:53:34.698 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64 11-May-2018 11:53:34.699 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: D:\Program Files\Java\jdk1.8.0_161\jre 11-May-2018 11:53:34.703 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_161-b12 11-May-2018 11:53:34.704 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation 11-May-2018 11:53:34.706 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: D:\work\apache-tomcat-8.5.29 11-May-2018 11:53:34.708 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: D:\work\apache-tomcat-8.5.29 11-May-2018 11:53:34.708 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=D:\work\apache-tomcat-8.5.29\conf\logging.properties 11-May-2018 11:53:34.709 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 11-May-2018 11:53:34.710 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048 11-May-2018 11:53:34.714 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 11-May-2018 11:53:34.718 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs= 11-May-2018 11:53:34.723 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=D:\work\apache-tomcat-8.5.29 11-May-2018 11:53:34.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=D:\work\apache-tomcat-8.5.29 11-May-2018 11:53:34.731 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=D:\work\apache-tomcat-8.5.29\temp 11-May-2018 11:53:34.739 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.16] using APR version [1.6.3]. 11-May-2018 11:53:34.740 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. 11-May-2018 11:53:34.741 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 11-May-2018 11:53:35.865 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.0.2m 2 Nov 2017] 11-May-2018 11:53:36.129 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"] 11-May-2018 11:53:36.509 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 11-May-2018 11:53:36.519 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"] 11-May-2018 11:53:36.532 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 11-May-2018 11:53:36.533 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 2548 ms 11-May-2018 11:53:36.584 信息 [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 11-May-2018 11:53:36.584 信息 [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.29 11-May-2018 11:53:36.629 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [D:\work\apache-tomcat-8.5.29\webapps\chapter02-2.0.1.RELEASE.war] 11-May-2018 11:53:40.555 信息 [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 11-May-2018 11:53:41.025 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [D:\work\apache-tomcat-8.5.29\webapps\chapter02-2.0.1.RELEASE.war] has finished in [4,393] ms 11-May-2018 11:53:41.148 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\work\apache-tomcat-8.5.29\webapps\docs] 11-May-2018 11:53:41.258 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\work\apache-tomcat-8.5.29\webapps\docs] has finished in [119] ms 11-May-2018 11:53:41.266 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\work\apache-tomcat-8.5.29\webapps\examples] 11-May-2018 11:53:41.987 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\work\apache-tomcat-8.5.29\webapps\examples] has finished in [721] ms 11-May-2018 11:53:42.048 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\work\apache-tomcat-8.5.29\webapps\host-manager] 11-May-2018 11:53:42.114 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\work\apache-tomcat-8.5.29\webapps\host-manager] has finished in [66] ms 11-May-2018 11:53:42.116 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\work\apache-tomcat-8.5.29\webapps\manager] 11-May-2018 11:53:42.175 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\work\apache-tomcat-8.5.29\webapps\manager] has finished in [59] ms 11-May-2018 11:53:42.176 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\work\apache-tomcat-8.5.29\webapps\ROOT] 11-May-2018 11:53:42.240 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\work\apache-tomcat-8.5.29\webapps\ROOT] has finished in [64] ms 11-May-2018 11:53:42.254 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 11-May-2018 11:53:42.274 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"] 11-May-2018 11:53:42.284 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 5749 ms

查看tomcat的App服务 http://localhost:8080/manager/html

SpringBoot 2.0 系列002

  • 4、点击chapter02-2.0.1.RELEASE访问 我们部署的项目。

    SpringBoot 2.0 系列002

2. SpringBoot是怎么运行起来的?

我们以jar文件方式为例进行讲解。

2.1 jar文件目录结构

  • 切入jar文件所在目录,执行命令:

D:\work\xxxxx\SpringBootLearn\chapter02\target>jar tf chapter02-2.0.1.RELEASE.jar META-INF/ META-INF/MANIFEST.MF org/ org/springframework/ org/springframework/boot/ org/springframework/boot/loader/ org/springframework/boot/loader/util/ org/springframework/boot/loader/util/SystemPropertyUtils.class org/springframework/boot/loader/PropertiesLauncher$1.class org/springframework/boot/loader/PropertiesLauncher$PrefixMatchingArchiveFilter.class org/springframework/boot/loader/Launcher.class org/springframework/boot/loader/PropertiesLauncher$ArchiveEntryFilter.class org/springframework/boot/loader/PropertiesLauncher.class org/springframework/boot/loader/jar/ org/springframework/boot/loader/jar/JarURLConnection.class org/springframework/boot/loader/jar/JarURLConnection$1.class org/springframework/boot/loader/jar/Bytes.class org/springframework/boot/loader/jar/JarURLConnection$JarEntryName.class org/springframework/boot/loader/jar/JarFileEntries$1.class org/springframework/boot/loader/jar/JarEntry.class org/springframework/boot/loader/jar/JarFileEntries.class org/springframework/boot/loader/jar/JarEntryFilter.class org/springframework/boot/loader/jar/ZipInflaterInputStream.class org/springframework/boot/loader/jar/StringSequence.class org/springframework/boot/loader/jar/JarFile$1.class org/springframework/boot/loader/ExecutableArchiveLauncher.class org/springframework/boot/loader/archive/ org/springframework/boot/loader/archive/JarFileArchive$JarFileEntry.class org/springframework/boot/loader/archive/ExplodedArchive$FileEntryIterator.class org/springframework/boot/loader/archive/ExplodedArchive$FileEntry.class org/springframework/boot/loader/archive/ExplodedArchive.class org/springframework/boot/loader/archive/ExplodedArchive$1.class org/springframework/boot/loader/archive/JarFileArchive$EntryIterator.class org/springframework/boot/loader/archive/Archive$Entry.class org/springframework/boot/loader/archive/Archive.class org/springframework/boot/loader/archive/Archive$EntryFilter.class org/springframework/boot/loader/archive/ExplodedArchive$FileEntryIterator$EntryComparator.class org/springframework/boot/loader/archive/JarFileArchive.class org/springframework/boot/loader/data/ org/springframework/boot/loader/data/RandomAccessDataFile$FileAccess.class org/springframework/boot/loader/data/RandomAccessDataFile$DataInputStream.class org/springframework/boot/loader/JarLauncher.class org/springframework/boot/loader/jar/JarFile.class org/springframework/boot/loader/jar/CentralDirectoryParser.class org/springframework/boot/loader/jar/AsciiBytes.class org/springframework/boot/loader/jar/FileHeader.class org/springframework/boot/loader/jar/JarFile$JarFileType.class org/springframework/boot/loader/jar/Handler.class org/springframework/boot/loader/jar/JarFileEntries$EntryIterator.class org/springframework/boot/loader/jar/CentralDirectoryVisitor.class org/springframework/boot/loader/jar/CentralDirectoryEndRecord.class org/springframework/boot/loader/jar/CentralDirectoryFileHeader.class org/springframework/boot/loader/jar/JarFile$2.class org/springframework/boot/loader/LaunchedURLClassLoader.class org/springframework/boot/loader/MainMethodRunner.class org/springframework/boot/loader/data/RandomAccessDataFile.class org/springframework/boot/loader/WarLauncher.class org/springframework/boot/loader/data/RandomAccessDataFile$1.class org/springframework/boot/loader/data/RandomAccessData.class org/springframework/boot/loader/LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class BOOT-INF/ BOOT-INF/classes/ BOOT-INF/classes/com/ BOOT-INF/classes/com/ricky/ META-INF/maven/ META-INF/maven/chapter02/ META-INF/maven/chapter02/chapter02/ BOOT-INF/classes/com/ricky/SpringBootApplication.class META-INF/maven/chapter02/chapter02/pom.properties META-INF/maven/chapter02/chapter02/pom.xml BOOT-INF/lib/ BOOT-INF/lib/spring-boot-starter-web-2.0.1.RELEASE.jar BOOT-INF/lib/spring-boot-starter-2.0.1.RELEASE.jar BOOT-INF/lib/spring-boot-2.0.1.RELEASE.jar BOOT-INF/lib/spring-boot-autoconfigure-2.0.1.RELEASE.jar BOOT-INF/lib/spring-boot-starter-logging-2.0.1.RELEASE.jar BOOT-INF/lib/logback-classic-1.2.3.jar BOOT-INF/lib/logback-core-1.2.3.jar BOOT-INF/lib/slf4j-api-1.7.25.jar BOOT-INF/lib/log4j-to-slf4j-2.10.0.jar BOOT-INF/lib/log4j-api-2.10.0.jar BOOT-INF/lib/jul-to-slf4j-1.7.25.jar BOOT-INF/lib/javax.annotation-api-1.3.2.jar BOOT-INF/lib/spring-core-5.0.5.RELEASE.jar BOOT-INF/lib/spring-jcl-5.0.5.RELEASE.jar BOOT-INF/lib/snakeyaml-1.19.jar BOOT-INF/lib/spring-boot-starter-json-2.0.1.RELEASE.jar BOOT-INF/lib/jackson-databind-2.9.5.jar BOOT-INF/lib/jackson-annotations-2.9.0.jar BOOT-INF/lib/jackson-core-2.9.5.jar BOOT-INF/lib/jackson-datatype-jdk8-2.9.5.jar BOOT-INF/lib/jackson-datatype-jsr310-2.9.5.jar BOOT-INF/lib/jackson-module-parameter-names-2.9.5.jar BOOT-INF/lib/spring-boot-starter-tomcat-2.0.1.RELEASE.jar BOOT-INF/lib/tomcat-embed-core-8.5.29.jar BOOT-INF/lib/tomcat-embed-el-8.5.29.jar BOOT-INF/lib/tomcat-embed-websocket-8.5.29.jar BOOT-INF/lib/hibernate-validator-6.0.9.Final.jar BOOT-INF/lib/validation-api-2.0.1.Final.jar BOOT-INF/lib/jboss-logging-3.3.2.Final.jar BOOT-INF/lib/classmate-1.3.4.jar BOOT-INF/lib/spring-web-5.0.5.RELEASE.jar BOOT-INF/lib/spring-beans-5.0.5.RELEASE.jar BOOT-INF/lib/spring-webmvc-5.0.5.RELEASE.jar BOOT-INF/lib/spring-aop-5.0.5.RELEASE.jar BOOT-INF/lib/spring-context-5.0.5.RELEASE.jar BOOT-INF/lib/spring-expression-5.0.5.RELEASE.jar

  • 打开MANIFEST.MF文件

Manifest-Version: 1.0 Implementation-Title: chapter01 Maven Webapp Implementation-Version: 2.0.1.RELEASE Built-By: zdwljs Implementation-Vendor-Id: chapter02 Spring-Boot-Version: 2.0.1.RELEASE Main-Class: org.springframework.boot.loader.JarLauncher Start-Class: com.ricky.SpringBootApplication Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Created-By: Apache Maven 3.3.9 Build-Jdk: 1.8.0_161 Implementation-URL: http://www.example.com

Start-class是我们的SpringBootApplication类,即jar文件方式启动 跟开发环境右键main方法运行方式一致

Main-Class则是JarLauncher。如果打包方式是war的话则是WarLauncher。此类工作内容是讲字节码文件加载到jvm中。

2.2 SpringBoot执行

由上述分析可知,com.ricky.SpringBootApplication是我们加载SB的入口。

  • 入口

SpringApplication 的静态run方法。也可以手动new SpringApplication

SpringApplication.run(SpringBootApplication.class,args);

    • 入口调用链1

    /** * 调用run方法 返回ConfigurableApplicationContext对象 此对象用法在03章节做讲解 */ public static ConfigurableApplicationContext run(Class primarySource, String... args) { return run(new Class[] { primarySource }, args); }

    • 入口调用链1

    /** * 此处有两步处理 * 1. 创建SpringApplication 对象 * 2. 执行该对象的run方法 */ public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); }

  • 创建SpringApplication 对象的过程

    • 第一步 调用构造方法

      //调用构造方法 public SpringApplication(Class<?>... primarySources) { this(null, primarySources); }

    • 第2步 调用构造方法

      //调用构造方法 public SpringApplication(Class<?>... primarySources) { this(null, primarySources); }

    • 第3步 具体构造方法解析

      //调用构造方法 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { //默认resourceLoader 为null this.resourceLoader = resourceLoader; //校验primarySources不为空 Assert.notNull(primarySources, "PrimarySources must not be null"); //赋值primarySources集合对象 说明此处是可以传递多个.class对象 当我们的启动类不在同一级包中 // com.ricky/ricky02 我们的启动类在ricky中,默认是只扫描ricky包中的类,如果想扫描ricky02中 可以将需要扫描的类放到此处。 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); //加载webApplicationType 对象 推断是web环境 还是非web环境 this.webApplicationType = deduceWebApplicationType(); //设置实例为ApplicationContextInitializer的Spring工厂实例 //可以通过spring.factories文件注入 继承自ApplicationContextInitializer的类 //也可以调用addInitializer方法手动注入 setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); //注入ApplicationListener实例的监听 实现方式类似上边 通过文件或者add方法都可以 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // 通过堆栈里获取的方式,判断main函数,找到原始启动的main函数 this.mainApplicationClass = deduceMainApplicationClass(); }

    • 第4步 run方法说明

      //执行run方法 返回ConfigurableApplicationContext 对象 public ConfigurableApplicationContext run(String... args) { //开启执行时间记录器 StopWatch stopWatch = new StopWatch(); stopWatch.start(); //定义context ConfigurableApplicationContext context = null; //定义exceptionReporters Collection exceptionReporters = new ArrayList<>(); //设置java.awt.headless模式 主要是在缺少显示设备和键盘鼠标等下的支持 设置系统变量为true configureHeadlessProperty(); //根据传递的参数 加载spirng.factories中的SpringApplicationRunListener实例监听对象 SpringApplicationRunListeners listeners = getRunListeners(args); //启动监听 listeners.starting(); try { // 将传入的参数转换为ApplicationArguments格式 ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); // 根据applicationArguments准备基础环境变量 监听listeners变量 绑定到Spring中 //如果webApplicationType是0则做下转换处理 最后 attach做些检查判断处理 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 从环境变量中检查和设置spring.beaninfo.ignore的状态 true或false configureIgnoreBeanInfo(environment); // 从环境变量中检查和设置banner.mode的模式 OFF时不打印 // 这部分是sb项目启动时显示几行springboot字符串头像 //自定义配置可参阅 SpringApplicationBannerPrinter Banner printedBanner = printBanner(environment); //创建应用上下文环境 检查是web环境还是默认环境等生成相对应环境 context = createApplicationContext(); // 从spring.factories中获取SpringBootExceptionReporter类型的实例 exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); //准备context // 参阅第五步 prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新上下文context 注意根据ServletWeb和ReactiveWeb以及默认的applicationContext的不同来进行具体刷新 refreshContext(context); // 刷新后的操作 现在是保留方法 afterRefresh(context, applicationArguments); //结束执行时间记录器 stopWatch.stop(); // 是否开启启动日志 if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } // 发布事件 context.publishEvent(ApplicationStartedEvent) listeners.started(context); // 将ApplicationRunner和CommandLineRunner类型的回调处理 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { // context.publishEvent(ApplicationReadyEvent) 发布监听 listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }

    • 第5步 准备context

      private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { // 设置context环境变量 context.setEnvironment(environment); // 注册internalConfigurationBeanNameGenerator实例 setResourceLoader 或者setClassLoader postProcessApplicationContext(context); // 执行ApplicationContextInitializer.initialize方法 applyInitializers(context); // 设置监听上下文 listeners.contextPrepared(context); // 如果启动日志开的话 则启动日志实例 if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans // 通过bean工厂注册springApplicationArguments的单例对象 context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); // 如果 printedBanner 不为空则通过bean工厂注册springBootBanner的单例对象 if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } // Load the sources 加载sources Set sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty");
      //通过 createBeanDefinitionLoader方法 获取lBeanDefinitionLoader 并设置beanNameGenerator、environment、resourceLoader // 最后根据类型进行装载registerbean 常见的类型有xml ,annotation,package,resouces等等 最后返回bean数量 load(context, sources.toArray(new Object[0]));
      // 通过SimpleApplicationEventMulticaster的Executor 去invoke是ApplicationListener类型的listener // 循环执行listener.onApplicationEvent(event); listeners.contextLoaded(context); }

      2.3 总结

      通过分析,我们发现sb在启动的时候会校验执行环境(web或者其他),根据args传入参数的不同执行不同逻辑,同时扫描的方式有包类型、resource、注解、xml等(load方法装载bean实例)。 还可以根据spring.factories注入listener 、Initializers、event等等对象。

      SpringBoot 2.0 系列002

      演示项目地址,欢迎fork和star

      码云:SpringBootLearn

      最后

      • 作者ricky
      • 交流群:244930845
      点赞
      收藏
      评论区
      推荐文章
      刚刚好 刚刚好
      2个月前
      css问题
      1、 在IOS中图片不显示(给图片加了圆角或者img没有父级) <div<img src""/</div div {width: 20px; height: 20px; borderradius: 20px; overflow: h
      blmius blmius
      1年前
      MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
      文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
      晴空闲云 晴空闲云
      2个月前
      css中box-sizing解放盒子实际宽高计算
      我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。 盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
      艾木酱 艾木酱
      1个月前
      快速入门|使用MemFire Cloud构建React Native应用程序
      > MemFire Cloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
      Stella981 Stella981
      1年前
      KVM调整cpu和内存
      一.修改kvm虚拟机的配置 1、virsh edit centos7 找到“memory”和“vcpu”标签,将 <name>centos7</name> <uuid>2220a6d1-a36a-4fbb-8523-e078b3dfe795</uuid>
      Wesley13 Wesley13
      1年前
      MySQL查询按照指定规则排序
      1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
      Stella981 Stella981
      1年前
      Docker 部署SpringBoot项目不香吗?
        公众号改版后文章乱序推荐,希望你可以点击上方“**Java进阶架构师**”,点击右上角,将我们设为**★**“**星标**”!这样才不会错过每日进阶架构文章呀。   ![](http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)   **2
      Stella981 Stella981
      1年前
      Angular material mat
      Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
      Wesley13 Wesley13
      1年前
      MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
      #### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
      helloworld_34035044 helloworld_34035044
      4个月前
      皕杰报表之UUID
      ​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为
      helloworld_28799839 helloworld_28799839
      2个月前
      常用知识整理
      # Javascript ## 判断对象是否为空 ```js Object.keys(myObject).length === 0 ``` ## 经常使用的三元运算 > 我们经常遇到处理表格列状态字段如 `status` 的时候可以用到 ``` vue