springboot启动方式
两种
1.jar包方式
2.war包方式
jar包
1. Application.java中main方法SpringApplication.run(Application.class,args);
2.java -jar application.jar
3.以spring内嵌的tomcat启动,这种方式需要一个jar
war包
1.Application.java extends SpringBootServletInitializer
2.重写configure方法,builder.sources(Application.class)
3.这是以外部tomcat启动的
原理:
SpringBootServletInitializer实现了WebApplicationInitializer,这个WebApplicationInitialzer是spring-web.jar的类;
通过spi实现了Serlvet3.0规范,在spring-web.jar/META-INF/services/javax.servlet.ServletContainerInitilizer文件里,加载了SpringServletContainerInitializer
这个SpringServletContainerInitializer implements ServletContainerInitializer
ServletContainerInitializer是在servlet-api.jar中,是一个servlet3.0规范的接口,tomcat启动会加载这个接口的实现。所以也就会加载SpringServletContainerInitializer
在SpringServletContainerInitializer中通过serlvet-api.jar的注解@HandlerTypes(WebApplicationInitializer.class),在onStartup()方法中把实现了WebApplicationInitializer的类放到参数集合SetClass? webAppInitializerClasses中,这个集合中就有前面的SpringBootServletInitializer
Springboot启动过程
元注解
元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。
FactoryBean getObject
1. 静态注入
2. 动态引入
基于ImportSelector接口实现
3. 基于ImportBeanDefinition
4. spring.factories
@conditional 加载到容器的条件
第一个决定要加载的类型, 第二个决定是否加载?
扩展下. 其实springCloud组件 很多用到@Import @Conditional , 还有些select等, 顺藤摸瓜 我简答列列举几个:
@SpringBootApplication--@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
@Import(AutoConfigurationImportSelector.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
重点说下Selector:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {}
最顶层继承了ImportSelector 和 Aware接口:
public interface ImportSelector {
}
protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
ListString configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
protected Class? getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
其实最终是寻找EnableAutoConfiguration对应的类组合, EnableAutoConfiguration来自package org.springframework.boot.autoconfigure;
所以最终初始化时, 是加载了spring-boot-autoconfigure里面的spring.factories的内容, 简单列举出现:
说明下:
SpringFactoriesLoader属于Spring框架私有的一种扩
展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。
public final class SpringFactoriesLoader {
}
springboot启动流程
springboot启动流程如下:
启动流程主要分为三个部分,第一部分进行、SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器,第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块。
及核心的创建上下文环境模块,第三部分是自动化配置模块,该模块作为springboot自动配置核心,在后面的分析中会详细讨论。在下面的启动程序中我们会串联起结构中的主要功能。
启动过程主要做了以下几件事情:
配置属性、获取监听器,发布应用开始启动事件初、始化输入参数、配置环境,输出banner、创建上下文、预处理上下文、刷新上下文(加载tomcat容器)、再刷新上下文、发布应用已经启动事件、发布应用启动完成事件。
在SpringBoot中启动tomcat的工作在刷新上下这一步。
而tomcat的启动主要是实例化两个组件:Connector、Container,一个tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个Connector和一个Container,而一个Container下又包含多个子容器。
Springboot的启动方式
Spring-Boot 的启动方式主要有三种:
1、运行带有 main 方法类
2、通过命令行 java -jar 的方式
3、通过 spring-boot-plugin 的方式
一、执行带有 main 方法类
这种方式很简单,我主要是通过 IDAE 的方式,进行执行。这种方式在启动的时候,会去自动加载 classpath 下的配置文件。
在 IDEA 中,可以通过配置 application 的方式配置上自己请求参数。
二、通过 java -jar 的方式
java-jar jar_path --param
jar_path: 指代将项目打包为jar打包之后的存储路径。
--param: 为需要在命令行指定的参数。
例如:
java-jar emample.jar --server.port=8081
该命令通过在启动行指定了项目启动后绑定的端口号,因为该命令行参数,将会覆盖 application.properties 中的端口配置
三、通过 spring-boot-plugin 方式启动
如果需要正常使用该 Maven 插件,需要我们在 Maven 项目中增加以下插件配置:
plugin
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-maven-plugin/artifactId
/plugin
注: 因为我在项目中指定了父模块 spring-boot-starter-parent。因此我不需要单独指定插件版本,该父模块会自动匹配与当前 spring-boot 版本相匹配的查件版本。
parent
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-parent/artifactIdversion1.5.10.RELEASE/version
/parent
准备工作做好之后,我们需要进入项目的根目录,执行
mvnspring-boot:run
该命令能够正常启动项目,但是如何为其指定执行参数呢?
spring-boot:run 该 Maven 查件在插件首页中指定了相关能够使用的可选参数:
通过查阅文档,可以通过命令的方式查看具体选项的意义以及用法:
mvn spring-boot:help-Ddetail
其中 arguments 的描述中,大意为:指定的参数会传递给具体应用,如果有多个参数需要指定,以","进行分割。具体用法通过 run.arguments 来指定:
mvnspring-boot:run -Drun.arguments="--server.port=8888"
以上就是三种启动方式的描述。