首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原 荐 SpringBoot 2.0 系列0

原 荐 SpringBoot 2.0 系列0

作者头像
石奈子
发布2018-06-13 15:37:03
8740
发布2018-06-13 15:37:03
举报

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文件需要加入

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>

打包方式选择为jar

<packaging>jar</packaging>

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

运行方式1,如下

运行方式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依赖。
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--排除tomcat依赖-->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--引入servlet支持-->
        <!--servlet依赖-->
        <!--httpServletRequest等相关文件-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--引入servlet支持结束-->
1.3.2 注意将打包方式改为war形式
<packaging>war</packaging>
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目录下 
  • 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

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

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<SpringBootExceptionReporter> 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<Object> 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 Object0)); 		             // 通过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等等对象。

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

码云:SpringBootLearn

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringBoot 2.0 系列002 --运行流程分析
    • 1. SpringBoot运行的几种方式
      • 1.1 开发环境,右键配置类main方法运行
      • 1.2 jar文件运行
      • 1.3 war包方式
    • 2. SpringBoot是怎么运行起来的?
      • 演示项目地址,欢迎fork和star
      相关产品与服务
      云数据库 MySQL
      腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档