上一篇我们看到,我们很轻松的完成了项目的构建,那么SpringBoot是如何做到的呢,在使用的使用又有哪些通用配置和注意事项呢?
其实SpringBoot给我们做了大量的自动配置功能,我们只需要引入对应的启动器就可以直接使用,
作为SpringBoot的使用者,一定要对其原理有一个大致的了解,避免遇到问题时无法跟踪。 接下来我们来分析分析。
启动原理和执行原理分析
一、SpringBoot 的启动原理
我们打开POM.XML, 注意看下面两个依赖:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
我们第一步是继承了父项目:spring-boot-starter-parent, 然后在添加 spring-boot-starter-web (WEB启动器)的依赖,项目就会自动给我们导入关于WEB项目所需要的配置和JAR。如图:
可能我们还有疑问,为什么一个mian方法就可以直接运行了,我们看看main方法类。
整个方法中, 就注解 @SpringBootApplication 和 SpringApplication 是我们不认识的,也比较脸生, 而且项目的启动也是从这里运行的,那么我们就来看看他们是个啥,
我们先看直接,我们把鼠标移动到注解上面。
发现他是一个组合注解, 里面很有很注解,我们来对每个注解来分析一下:
前面 4 个是注解的元数据信息, 我们主要看后面 3 个注解:
@SpringBootConfiguration 点击进去,我们发现使用的是 Spring 的 @Configuration
所以,到这里我们就可以知道,SpringBoot使用的是 @Configuration 的方式来配置IOC容器,@Configuration 就好比对应我们原来的一个XML配置文件(SpringBoot社区推荐使用基于JavaConfig的配置形式), 比如:
我们原来是这么写:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">
<!-- spring配置duid数据库连接池的数据源 by 杨攀 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
.....省略
</bean>
</beans>
而现在可以用JavaConfig这么配置:
/**
*@Description: 阿里连接池
*@Author:杨攀
*@Since:2019年1月6日下午5:18:02
*/
@Configuration
public class DruidDataSourceConfig {
@Bean
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
//设置参数
//.....省略
return dataSource;
}
在该类中标注了 @Bean 的方法返回的实例,都会注入到IOC容器中,而bean的id默认为方法名。(注意:@Configuration 是spring的注解,不是springboot的,本身spring提供了JavaConfig的配置)。
@EnableAutoConfiguration 注解,如果熟悉Spring框架的人都知道, Spring中也定义了很多@Enable开头的注解, 比如: @EnableCaching等,如图
他们都是通过@import来导入对应的配置类。 SpringBoot 也是一样, @EnableAutoConfiguration点击进入,也是通过@import来导入的。将所有符合自动配置条件的bean定义加载到IOC容器中
其中:
@AutoConfigurationPackage 自动配置包注解, 点击进去后,我们可以看到源代码:
其实这里就是把bean注册到spring中, 我们可以断点看看
上图中,我们已经看到扫描到的包是 com.topinfo.yangp,就是我们main方法类的包及子包都会被扫描并注册。
我们继续更进,在添加后,发现txApplication已经注册到Spring中了。
所以,我们在写启动类的时候,我们需要放在项目的顶级包中,以便SpringBoot进行扫描。
@Import(AutoConfigurationImportSelector.class) 导入注解,从名称上来看,它导入了一个自动配置导入选择器, 我们点击进去
它实现了多个接口,并实现了一个 selectImports
然后我们点击 100 行, 继续跟进去
我们看 199 行, getCandidateConfigurations 根据获取配置,点击
会去读取一个 spring.factories 的文件,读取不到会表这个错误,我们继续根据会看到,最终路径的长这样,而这个是spring提供的一个工具类。
它其实是去加载一个外部的文件,而这文件是在
我们打开这个文件,发现其有很多很多的自动配置类,包括SpringMVC,这就是为什么我们一开始就可以直接使用mvc的原因,如图:
就这样,@EnableAutoConfiguration就是从classpath中搜寻META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的配置类,并加载到IOC容器中。
@ComponentScan 包扫描,就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中
这样,关于 @SpringBootApplication 的注解的功能就分析差不多了, 简单来说就是 3 个注解的组合注解,如:
@SpringBootApplication
|- @SpringBootConfiguration
|- @Configuration //通过javaConfig的方式来添加组件到IOC容器中
|- @EnableAutoConfiguration
|- @AutoConfigurationPackage //自动配置包,与@ComponentScan扫描到的添加到IOC
|- @Import(AutoConfigurationImportSelector.class) //到META-INF/spring.factories中定义的bean添加到IOC容器中
|- @ComponentScan 包扫描
关于SpringBoot的启动原理就差不多了。
二、SpringBoot 的执行原理
就是,嗯,注解我们刚刚看过了,我们现在来看看为什么mian方法执行后,项目就直接启动了,我们再来瞄一眼main方法:
直觉告诉我们,我们肯定从run方法入手,如图:
方法中,先创建了一个SpringApplication的实例,然后调用实例的run方法,我们先看看new实例的时候做了什么,点击进去查看,
点击267行
我们可以看到,其实他主要做了几个事情:
1、根据classpath里面是否存在某个特征类来判断是否应该创建一个为Web应用使用的ApplicationContext类型
2、在应用的classpath中查找并加载所有可用的ApplicationContextInitializer
3、在应用的classpath中查找并加载所有可用的ApplicationListener
然后执行run方法。 我们看run方法,跟踪后,我们可以看到run方法的内部实现。
到此,SpringBoot的启动执行就差不多了,,后面我们在将下SpringBoot的常用配置
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。