SpringBoot 核心理论
1.SpringBoot
1.1 概念
SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
- 设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
- 核心:自动配置、基于 约定大于配置 原则。
- 父依赖维护 SpringBoot 版本号即可
- 核心注解:@EnableAutoConfiguration
1.2 核心依赖
SpringBoot 父依赖为核心依赖,其中默认管理了很多 jar 包的版本,所以我们再根 pom.xml 中如果不需要指定特殊的版本,可不指定 jar 包版本。
查看核心依赖
- 进入 spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<!-- 跟进 以下目录,查看父依赖的 -->
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
- 进入spring-boot-dependencies
<!-- 再进入 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
进入 spring-boot-dependencies-2.3.1.RELEASE.pom 文件后,可发现在 properties
和 dependencyManagement
中有很多依赖已经配置并指定版本号好。
1.3 自动装配(核心)
SpringBoot 的核心就在于 自动装配。
SpringBoot 自动装配的过程:
SpringBoot 通过 @EnableAutoConfiguration 注解开启自动装配;加载 spring.factories 中注册的各类 AutoConfiguration;当 AutoConfiguration 类满足 @Conditional 注解中的条件时,则实例化该 AutoConfiguration 类中定义的 Bean,并注入 Spring 容器中。
@EnableAutoConfiguration
该注解由 @SpringBootApplication 引入,完成开启自动装配;扫描 autoconfigure jar 包 META-INF 下的 spring.factories 文件,并加载其中注册的 AutoConfigure 类等。
spring.factories
配置文件,位于 autoconfigure jar 包 META-INF 目录下;
AutoConfiguration
SpringBoot 中的自动配置类,例如 RedisAutoConfiguration 等;其中定义了三方组件集成 Spring 所需的初始化 Bean 和条件
@Conditional
SpringBoot 中以 @Conditional 开头的条件注解;AutoConfiguration 需满足其中的条件才可实例化
1.3 启动器
各类三方组件starter
<!-- Spring web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- SpringBoot JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- SpringBoot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.4 注解
SpringBoot 项目创建完会生成 ***Application 启动类;
package pers.vincent.matrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MatrixApplication {
public static void main(String[] args) {
SpringApplication.run(MatrixApplication.class, args);
}
}
核心注解:@SpringBootApplication
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.repository.Repository;
@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 {
// 排除指定自动配置类
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
// 排除指定自动配置名
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
// 指定扫描的基础包,激活注解组件的初始化
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
// 指定扫描的类,初始化
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
// Bean名称生成器
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
// 指定是否代理 @Bean 方法
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
结构:
@SpringBootApplication
- @SpringBootConfiguration
- @Configuration
- @Component
- @Configuration
- @EnableAutoConfiguration
- @AutoConfigurationPackage
- @Import(AutoConfigurationImportSelector.class)
- @ComponentScan
- @Repeatable(ComponentScans.class)
@SpringBootConfiguration: SpringBoot 配置
@Configuration:Spring 配置类
@Component:组件
@EnableAutoConfiguration:自动配置 (核心注解)
@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class):自动配置`包注册`
@Import(AutoConfigurationImportSelector.class): 自动配置导入选择
@ConditionOnxxxx:如果条件都满足,才能生效
@ComponentScan:扫描
其余注解:
- @AliasFor:用于桥接到其他注解,其中的属性指定所桥接的注解类
@EnableAutoConfiguration :
@Import(AutoConfigurationImportSelector.class)
AutoConfigurationImportSelector 核心功能解析:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 加载 spring.factories 中的 EnableAutoConfiguration 的配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 配置类去重
configurations = removeDuplicates(configurations);
/// 获得被排除的类集合
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
// 检查排除的类是否合法
checkExcludedClasses(configurations, exclusions);
// 配置类集合中取出被排查的类
configurations.removeAll(exclusions);
// 过滤自动加载组件
configurations = getConfigurationClassFilter().filter(configurations);
// 将配置类和排除类 通过事件传入监听器中
fireAutoConfigurationImportEvents(configurations, exclusions);
// 返回自动配置类全限定名数组
return new AutoConfigurationEntry(configurations, exclusions);
}