目录
一.概述
SpringBoot简单来说就是是对spring,springmvc的一个高级封装,根据spring自己的spi机制加载spring.factories文件里的各种配置类。
一个仅依赖web环境的spirngboot项目,Springboot的启用原理可以概述为以下四步:
1、SpringApplication.run 会创建一个IOC容器: AnnotationConfigServletWebServerApplicationContext, @SpringBootApplication注解加载需要的自动配置类
2、IOC容器启动 onRefresh方法会启动Tomcat
3、Tomcat启动会加载所有的Servlet
4、Tomcat会调用Servlet的生命周期函数init(),DispatcherServlet就会加载九大组件的整个初始化流程
二.SpringBoot环境
搭建一个最简单的基于SpringMVC的SpringBoot项目 maven只需要配置下面两个依赖,
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
然后只要写下面几行代码,调用main方法,Springboot就会初始化IOC容器,启动内置tomcat,注册SpringMVC的DispatchServlet等操作。
通过分析@SpringBootApplication注解来了解springboot如何实现自动配置,然后分析run方法了解springboot的启动流程
@SpringBootApplication
public class SpringbootSourceApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSourceApplication.class, args);
}
}
三.自动配置原理
自动配置主要分析下@SpringBootApplication都做了什么,@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 {
@EnableAutoConfiguration注解上面又有两个关键的注解,
1.@AutoConfigurationPackage注解会扫描标注此注解的SpringbootSourceApplication(自己写的启动类)的类路径下的所有的类,将bean定义信息注册道容器,这也是springboot项目我们的组件通常写在启动类子包才能识别的原因,它默认就是从标了@SpringBootApplication注解的启动类下开始扫描的。
2.@Import(AutoConfigurationImportSelector.class) 这个注解导入的AutoConfigurationImportSelector组件实现了SpringBoot的自动配置
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
AutoConfigurationImportSelector类的getAutoConfigurationEntry方法基于spi机制(全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类)获取了所有的配置类,
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取所有候选配置这行代码追踪进去可以看到利用SpringFactoriesLoader加载了类路径下META-INF下的spring.factories文件来读取了 @EnableAutoConfiguration注解全类名对应的值
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取候选配置
List<String> configurations = getCandidateConfigurations(annotationMetadat