Spring框架主要构成
-
Spring框架主要有7个模块:
1.Spring AOP:面向切面编程思想,同时也提供了事务管理。
2.Spring ORM:提供了对Hibernate、myBatis的支持。
3.Spring DAO:提供了 对Data Access Object模式和JDBC的支持。实现业务逻辑与数据库访问代码分离,降低代码耦合度。
4.Spring Web:提供了Servlet监听器的Context和Web应用的上下文。
5.Spring Context:提供了Spring上下文环境,以及其他如国际化、Email等服务。
6.Spring MVC:提供了MVC设计模式的实现。
7.Spring core:提供了Spring框架基本功能(IOC功能),如BeanFactory以工厂模式创建所需对象、通过读取xml文件实例化对象、管理组件生命周期等。
SpringBoot框架的优点
1.快速构建专案。
2.对主流开发框架的无配置整合。
3.专案可独立执行,无须外部依赖Servlet容器。
4.提供执行时的应用监控。
5.极大的提高了开发、部署效率。
6.与云端计算的天然整合。
Spring Boot的主要执行流程
- 初始化Spring Application实例
-
初始化Spring Boot项目启动
源码角度分析流程
- 项目启动文件,入口就是这个main方法,
@SpringBootApplication
注解的作用下文有写到,这里不做赘述。
- 跟踪进入run方法,这个方法里面首先要创建一个
SpringApplication
对象实例,然后调用这个创建好的SpringApplication
的实例的run方法。
- 先看一下创建的实例的构造函数,发现构造函数进行了重载,
271行推断了web的应用类型,272行加载上下文初始化器,273行加载应用的事件监听器,274行推断引导类
3.1web应用的类型推断
根据WebApplicationType
这个类的静态方法deduceFromClasspath()
推断Web应用类型,其实也就是根据当前的应用 ClassPath 中是否存在相关实现类来推断 Web 应用的类型,类型有三种:
- Web Reactive:
WebApplicationType.REACTIVE
- Web Servlet:
WebApplicationType.SERVLET
- 非 Web:
WebApplicationType.NONE
- 根据上面的代码可以看出推断的逻辑:
- 当WEBFLUX_INDICATOR_CLASS存在并且WEBMVC_INDICATOR_CLASS和JERSEY_INDICATOR_CLASS都不存在的时候,Web的类型才会被推断成Web Reactive。
- 当WEBFLUX_INDICATOR_CLASS和SERVLET_INDICATOR_CLASSES都不存在的时候,Web的类型才会被推断成非 Web类型。
- 其它情况都会被推断成Web Servlet的类型,所以当Reactive和Servlet同时存在的时候,Reactive会被覆盖掉。
3.2加载应用上下文初始化器
利用 Spring 工厂加载机制,实例化 ApplicationContextInitializer
实现类,并排序对象集合。
3.3加载应用事件监听器
利用 Spring 工厂加载机制,实例化 ApplicationListener 实现类,并排序对象集合。其实这个和上下文的初始化器的加载时同样的原理。
3.4推断引导类
利用异常的堆栈信息来推断引导类,也就是我们启动Spring Boot项目的那个main方法所在的类。
通过异常的堆栈信息中方法名为main的栈帧来得到入口类的名字。
到这里SpringApplication就已经完成了在构造阶段所初始化的过程。
- 探究SpringApplication的运行阶段
当我们执行完new SpringApplication(primarySources)
后,就会调用该对象的run
方法。
public ConfigurableApplicationContext run(String... args) {
// 启动一个计时器
StopWatch stopWatch = new StopWatch();
// 开始计时
stopWatch.start();
// 定义局部变量
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 设置java.awt.headless系统属性为true - 没有图形化界面
configureHeadlessProperty();
// 1、加载SpringApplication运行监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
// 2、运行SpringApplication运行监听器,Spring应用刚启动
listeners.starting();
try {
// 根据传入的args,创建ApplicationArguments对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
// 4、创建 Environment,这里调用listeners.environmentPrepared(ConfigurableEnvironment)
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
// 打印Banner
Banner printedBanner = printBanner(environment);
// 5、创建Spring应用上下文
context = createApplicationContext();
// 异常分析报告的记录容器的初始化
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// Spring上下文前置处理,这里调用listeners.contextPrepared(context)和listeners.contextLoaded(context)
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
// Spring上下文刷新
refreshContext(context);
// Spring上下文后置处理
afterRefresh(context, applicationArguments);
// 停止计时
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
// Spring 应用已经启动
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// 处理异常,并会打印异常分析报告,并调用listeners.failed(context, exception);
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
// Spring 应用正在运行
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
总结
至此我们就完成了对Spring Boot项目启动的流程进行了简要的分析。我们可以知道
SpringApplication
主要分为两个阶段,一个是准备阶段主要进行Web类型推断、引导类推断、加载上下文初始化器和事件监听器,另一个是运行阶段主要进行加载运行SpringApplication
的运行监听器、监听Spring Boot事件、创建Environment、创建Spring应用上下文。这样就完成了一个Spring Boot应用的启动。
Spring Boot自动配置的基础知识和原理
配置文件能配置的属性参照(https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties)
自动配置原理
通过注解@SpringBootApplication
,SpringBoot启动时加载主配置类,开启了自动配置功能@EnableAutoConfiguration
。
-
@SpringBootConfiguration
:表面这是个配置类,开发者可以在这个类中配置Bean,类似Spring中的applicationContext.xml的角色 -
@EnableAutoConfiguration
:开启自动化配置,开发者可以使用自定义配置代替自动化配置。 -
@ComponentScan
:完成包扫描,默认扫描的类都位于当前类所在的包下面,所以项目启动类务必放在根包中,否则可能出现扫描不到的情况。
多环境配置
- 配置文件命名
- application-{profile}.properties
- profile对应环境标志
- dev:开发环境
- prod:生产环境
- 环境加载
-
由application.properties文件中的spring.profiles.active属性设置
-
配置原理
- Spring Boot应用可以编写多个配置类,使用@Configuration标志;
-
Spring Boot会将其汇集起来构建出一个完整的运行时环境。