Spring Boot 2.0之理解SpringApplication
-
- SpringApplication的基本使用
- SpringApplication 准备阶段
- SpringApplication 运行阶段
- 刷新上下文
SpringApplication的基本使用
SpringApplication 运行
SpringApplication.run(SpringApplicationBootstrap.class,args);
自定义 SpringApplication
通过 SpringApplication API 调整
SpringApplication springApplication = new SpringApplication(SpringApplicationBootstrap.class);
springApplication.setBannerMode(Banner.Mode.CONSOLE);
springApplication.setWebApplicationType(WebApplicationType.NONE);
springApplication.setAdditionalProfiles("prod");
springApplication.setHeadless(true);
通过 SpringApplicationBuilder API 调整
流式方法处理,更优雅
new SpringApplicationBuilder(SpringApplicationBootstrap.class)
.bannerMode(Banner.Mode.CONSOLE)
.web(WebApplicationType.NONE)
.profiles("prod")
.headless(true)
.run(args);
SpringApplication 准备阶段
配置 Spring Boot Bean 源
Java 配置 Class 或 XML 上下文配置文件集合,用于 Spring Boot BeanDefinitionLoader
读取并且将配置源解析加载为Spring Bean 定义
Java 配置 Class
用于 Spring 注解驱动中 Java 配置类,大多数情况是 Spring 模式注解所标注的类,如 @Configuration
。在spring boot中是@SpringBootApplication
@SpringBootApplication
—>@SpringBootConfiguration
—>@Configuration
/**
* {@link SpringApplication}
* Created by Yuk on 2019/3/9.
*/
@SpringBootApplication
public class SpringApplicationBootstrap {
public static void main(String[] args) {
SpringApplication.run(SpringApplicationBootstrap.class,args);
}
}
@SpringBootApplication
public class SpringApplicationBootstrap {
public static void main(String[] args) {
//SpringApplication.run(SpringApplicationBootstrap.class,args);
Set sources = new HashSet();
sources.add(SpringApplicationBootstrap.class.getName());
SpringApplication application = new SpringApplication();
application.setSources(new HashSet<>(sources));
application.run(args);
}
}
这两种方式都可以正常启动,重点看application.setSources(new HashSet<>(sources));
/**
* Set additional sources that will be used to create an ApplicationContext. A source
* can be: a class name, package name, or an XML resource location.
* <p>
* Sources set here will be used in addition to any primary sources set in the
* constructor.
* @param sources the application sources to set
* @see #SpringApplication(Class...)
* @see #getAllSources()
*/
public void setSources(Set<String> sources) {
Assert.notNull(sources, "Sources must not be null");
this.sources = new LinkedHashSet<>(sources);
}
看英文注释可以知道
A source can be: a class name, package name, or an XML resource location.
这里Set集合的sources可以是className(但必须是加了@Configuration
),可以是包名,也可以是spring的配置文件
推断 Web 应用类型
根据当前应用 ClassPath 中是否存在相关实现类来推断 Web 应用的类型,包括:
- Web Reactive: WebApplicationType.REACTIVE
- Web Servlet: WebApplicationType.SERVLET
- 非 Web: WebApplicationType.NONE
参考方法:
spring boot 2.0.7版本
this.webApplicationType = WebApplicationType.deduceFromClasspath();
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
推断引导类(Main Class)
这里可能会有个疑问,引导类不就是Main Class吗?
注意,这样写确实是的
@SpringBootApplication
public class SpringApplicationBootstrap {
public static void main(String[] args) {
SpringApplication.run(ApplicationConfiguration.class,args);
}
}
但是这样写,引导类就不是当前运行main方法的class了
public class SpringApplicationBootstrap {
public static void main(String[] args) {
SpringApplication.run(ApplicationConfiguration.class,args);