什么是Spring Boot
Spring Boot基本介绍
这里我直接引用官网的描述,
官网地址:http://spring.io/projects/spring-boot
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
Spring Boot 的特性
-
Create stand-alone Spring applications
-
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
-
Provide opinionated ‘starter’ dependencies to simplify your build configuration
-
Automatically configure Spring and 3rd party libraries whenever possible
-
Provide production-ready features such as metrics, health checks and externalized configuration
-
Absolutely no code generation and no requirement for XML configuration
Spring Boot启动原理
自动配置加载原理
这里咱们从SpringBoot的启动类开始,通过看SpringBoot的源码来逐步理解SpringBoot如何进行自动化配置
- 我这里使用的SpringBoot版本为2.0.0.RELEASE
SpringBoot启动类如下
@SpringBootApplication
public class BookshopApplication {
public static void main(String[] args) {
SpringApplication.run(BookshopApplication.class, args);
}
}
@SpringBootApplicaion是SpringBoot提供的一个注解,用于标志当前类是SpringBoot的启动类.那咱们从这个注解开始分析
@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 {
}
@Target、@Retention、@Documented、@Inherited这四个都是jdk自带的注解,给子含义如下
@Target:定义注解的作用目标
- ElementType.TYPE:注解作用于接口、类、枚举、注解
- ElementType.FIELD:注解作用于字段、枚举的常量
- ElementType.METHOD:注解作用于方法
- ElementType.PARAMETER:注解作用于方法参数
- ElementType.CONSTRUCTOR:注解作用于构造函数
- ElementType.LOCAL_VARIABLE:注解作用于局部变量
- ElementType.ANNOTATION_TYPE:注解作用于注解
- ElementType.PACKAGE:注解作用于包
@Retention:定义注解的保留策略
- RetentionPolicy.SOURCE:注解仅存在于源码中,在class字节码文件中不包含
- RetentionPolicy.CLASS:默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
- RetentionPolicy.RUNTIME:注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented:制作javadoc时,是否将注解信息加入文档
@Inherited:子类可以继承父类中的该注解
@SpringBootConfiguration是SpringBoot中的注解,咱们看看它的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration为Spring框架提供的注解,标注这个类是一个配置类
这里我们先来看@AutoConfigurationPackage,后面我们再来看导入的AutoConfigurationImportSelector类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
我们先来看@AutoConfigurationPackage
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
显而易见的是AutoConfigurationPackages中的Registrar类是此注解的关键,进去看看源码(这里我列出一些关键性的代码)
接下来我们去看register()方法
经过上面这个流程就把SpringBoot启动类所在的包下的所有java类都加载到Spring框架中了;也就是说SpringBoot只能管理启动类所在的包内的java类
下面我们回过头来看@EnableAutoConfiguration中的导入的AutoConfigurationImportSelector类,关键方法如下
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
其中最关键的是AutoConfigurationMetadataLoader.loadMetadata()方法,下面来分析此方法主要干了什么
那么META-INF/spring-autoconfigure-metadata.properties中道理配置了什么东西呢?我们可以在spring-boot-autoconfigure包中找到此配置文件,文件内容如下
可以看到,配置文件中有非常多的AutoConfiguration,那么这些Configuration是用来干嘛的呢?且看下回分解