Spring Boot 入门
1.Spring Boot简介
官方文档:https://spring.io/projects/spring-boot
- 简化Spring应用开发的一个框架;
- 整个Spring技术栈的一个大整合;
- J2EE开发的一站式解决方案;
2.微服务
微服务文档:https://martinfowler.com/articles/microservices.html#MicroservicesAndSoa
微服务是一种独特的架构设计模式,它将是软件、web或移动应用拆分为一系列独立的服务——如微服务。这些服务仅用于某一个特定的业务功能,例如:用户管理、用户角色、电子商务购物车、搜索引擎、社交媒体登录等。此外,它们是相互独立的,这意味着它们可以采用不同的编程语言和数据存储。微服务中几乎不存在集中管理,它使用轻量级的HTTP、REST或Thrift API来进行内部通信。
微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元;
3. Spring Boot — Hello word
项目创建方式一:
1. 创建一个maven项目 我这里是:springboot_study
2. 导入Spring Boot 相关的依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--插件:将应用打包成可执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3. 创建一个主程序,启动spring boot 应用
//标注一个程序类,说明这是一个springboot应用
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//启动springboot应用
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
4. 编写相关的Controller 、 Service
@Controller
public class HelloController {
@ResponseBody//不走视图解析器,返回字符串
@RequestMapping("/hello")
public String hello(){
return "hello world";
}
}
5. 运行主程序测试
6. 将项目打包成jar包
生成的jar包存放在target目录下
7. 直接使用 java -jar 命令执行
项目创建方式二:使用 IDEA 直接创建项目
1、创建一个新项目
2、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现
3、填写项目信息
4、选择初始化的组件(初学勾选 Web 即可)
5、填写项目路径
6、等待项目构建成功
--------------------创建后的项目结构分析-------------------
通过上面步骤完成了基础项目的创建。就会自动生成以下文件。
1、程序的主启动类
2、一个 application.properties 配置文件
3、一个 测试类
4、一个 pom.xml
剩余操作方法和上方项目创建方式一一致
4. Spring Boot 运行原理
我们来探索一下刚才的hello world程序是如何运行的
pom.xml配置文件
1.父项目
我们导入的父依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
当我们Ctrl 点击到这个父依赖里发现,
我们导入的父依赖,还有一个父亲依赖
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
这个依赖才是真正管理SpringBoot应用里所有版本的地方
(Spring Boot版本中心)
有了它我们以后导入依赖也就不需要版本了<version>
但是,如果没有在dependencies里管理的依赖
也自然就需要我们自己手都声明版本号
2. 导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-xxx : 就是spring boot的场景启动器
spring-boot-web : 帮我们导入了web模块运行所依赖的组件
SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;
spring官网定义的starter
主启动类(主入口类)
//标注一个程序类,说明这是一个springboot应用
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//启动springboot应用
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication
作用:标注在某个类上,用来声明这个类是一个Spring Boot的著配置类,Spring Boot 就应该运行这个类的 main 方法来启动Spring Boot 应用。
进入@SpringBootApplication这个注解中
@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 {...}
@ComponentScan
作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义在IOC容器中
@SpringBootConfiguration
作用:标注在某个类上,表示这是一个SpringBoot的配置类
我们进入到@SpringBootConfiguration中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {...}
这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
我们回到 SpringBootApplication 注解中继续看。
@EnableAutoConfiguration
作用:开启自动配置功能
以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
进入@EnableAutoConfiguration中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {...}
@AutoConfigurationPackage :自动配置包
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
@Import: Spring的底层注解@Import,给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
回到@EnableAutoConfiguration
@Import({AutoConfigurationImportSelector.class})
给容器导入组件
AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:
1.这个类中有个方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
这个方法又调用了 SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
这里它又调用了 loadSpringFactories 方法 进入查看
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryImplementationName = var9[var11];
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;
结论
- SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
- 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
- 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
- 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
- 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;
Spring Boot配置
1.配置文件
配置文件的作用 :修改SpringBoot自动配置的默认值
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
-
application.properties
语法结构 :key=value
-
application.yml
语法结构 :key:空格 value
2.yaml概述
YAML(YAML Ain’t Markup Language)
YAML A Markup Language:是一个标记语言
YAML isn’t Markup Language:不是一个标记语言;
这种语言以数据作为中心,而不是以标记语言为重点!
传统XML配置
<server>
<port>8081<port>
</server>
yaml配置
server:
port: 8081
3. yaml 基本语法
yaml语法要求严格
1. 空格不能省略
2. 利用缩进来控制层级关系,只要左边对齐一列数据就是同一级别的
3. 属性和值是大小写敏感的
1.值的写法
--------------------------------------------------------------
字面量:普通的值(数字,字符串,布尔)
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
key:空格 value
注意:
-
“ ” 双引号,会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: “ka \n sha” 输出 :ka 换行 sha -
‘’ 单引号,不会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘ka \n sha’ 输出 :ka \n sha
--------------------------------------------------------------
对象 Map
以键值对的方式
key:
value1: 空格 值
value2: 空格 值
在下一行来写对象的属性和值得关系,注意缩进;比如
student:
name: kasha
age: 18
注意中间的空格不要省略
行内写法
student: {name: kasha,age: 18}
注意中间的空格不要省略
数组 List 、 Set
用 - 值表示数组中的一个元素,比如:
anmials:
- cat
- pig
- dog
注意中间的空格不要省略
行内写法
animals: [cat,pig,dog]
注意中间的空格不要省略
2.配置文件 值的注入
--------------------yml配置文件注入--------------------
application.yml 配置文件
person:
name: 卡莎
age: 20
boss: false
maps: {key1: value1,key2: value2}
lists:
- 张三
- 李四
- 王五
dog:
dogName: 小狗
dogAge: 2
javaBean: Person
@ConfigurationProperties
/**
* @ConfigurationProperties
* 告知SpringBoot将本类中的所有属性和配置文件中相关配置进行绑定
* (prefix = "person")
* 表示将配置文件中person下的所有属性一一对应
*只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能
*/
@Component //注册bean到ioc
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private boolean boss;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
get set 有参无参 tostring
}
这时候Idea就会提示我们
这是因为我们没有导入配置文件处理器 所以我们需要在pom.xml中导入依赖
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
以上配置完后我们可以去Spring的测试类中测试一下
@SpringBootTest
class SpringBoot01ApplicationTests {
@Autowired
Person person ;
@Test
void contextLoads() {
System.out.println(person);
}
}
测试输出结果如下,证明值注入成功
Person{name='卡莎', age=20, boss=false,
maps={key1=value1, key2=value2},
ists=[张三, 李四, 王五],
dog=com.it.bean.Dog@49c8f6e8}
--------------------properties配置文件注入--------------------
application.propertis配置文件
person.name = 枯木逢春
person.age = 22
person.boss = false
person.maps.key1 = value1
person.maps.key2 = value2
person.lists= a,b,c,d
person.dog.dogName = dog
person.dog.dogAge = 1
javaBean Person 和上方配置相同或者使用@Value注入
我们这里使用@Value来注入
@Component //注册bean到ioc
//@ConfigurationProperties(prefix = "person")
public class Person {
/**
* @Value相当于 下面的value
* <bean id="person" class="com.it.bean.Person">
* <property name="name" value="xxx"></property>
* </bean>
*
*/
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@Value("${person.boss}")
private boolean boss;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
配置完成后测试,结果正常输出
【注意】properties配置文件在写中文的时候,会有乱码 , 我们需要去IDEA中设置编码格式为UTF-8;
settings–>FileEncodings 中配置;
对比@ConfigurationProperties 和 @Value注入
1、@ConfigurationProperties只需要写一次即可 ,
@Value则需要每个字段都添加
2、松散绑定: 比如我的yml中写的last-name,这个和lastName是一样的,
- 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 ,
可以保证数据的合法性 @Validated //语法校验
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
结论:
配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
如果我们在某个业务中,只需要获取配置文件中的某个值,
可以使用一下 @value;
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,
就直接@configurationProperties,不要犹豫!
@PropertySource和@ImportResource
@PropertySource: 加载指定的配置文件
@ConfigurationProperties 默认从全局配置文件中获取值
@PropertySource : 从指定配置文件中获取值
1.创建一个person.properties配置文件,这个配置文件用来注入bean中的值
person.name = 枯木逢春
person.age = 22
person.boss = false
person.maps.key1 = value1
person.maps.key2 = value2
person.lists= a,b,c,d
person.dog.dogName = dog
person.dog.dogAge = 1
2.在java bean 中注入这个配置文件中的值
@Component //注册bean到ioc
@PropertySource(value = {"classpath:person.properties"})
public class Person {
/**
* @Value相当于 下面的value
* <bean id="person" class="com.it.bean.Person">
* <property name="name" value="xxx"></property>
* </bean>
*
*/
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@Value("${person.boss}")
private boolean boss;
//复杂类型无法注入
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上
@ImportResource(locations = {"classpath:beans.xml"})
导入Spring的配置文件让其生效
<?xml version="1.0" encoding="UTF‐8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring‐beans.xsd">
<bean id="helloService" class="com.atguigu.springboot.service.HelloService"></bean>
</beans>
SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式
1、配置类@Configuration------>Spring配置文件
2、使用@Bean给容器中添加组件
//指明当前类是一个配置类;就是来替代之前的Spring配置文件
@Configuration
public class MyAppConfig {
/**
* @Bean <bean id=方法名 class=返回值类型></bean>
* 返回值 bean对象
*/
@Bean
public HelloService helloService(){
System.out.println("Spring 容器托管了HelloService组件");
return new HelloService();
}
}
3.测试
@Autowired
ApplicationContext context;
@Test
public void test1(){
//判断ioc容器中是否存在bean
boolean exists = context.containsBean("helloService");
System.out.println(exists);
}
配置文件占位符
- 随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
- 占位符获取之前配置的值,如果没有可以是用:指定默认值
person.last‐name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15
3.多环境切换 Profile
1、多Profile文件
我们在主配置文件编写的时候,文件名可以是 application{profile}.properties/yml
默认使用application.properties的配置;
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境
比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
spring.profiles.active=dev
yml多文档切换
我们只需要通过 - - - 三个横线来划分文档模块
spring: profiles: xxx 指定这个文档模块配置属于哪个环境
spring: profiles: active: xxx 选择要(激活)使用的模块
server:
port: 8081
#选择要激活的环境块
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles: dev #指定属于哪个环境
---
server:
port: 8083
spring:
profiles: prod #指定属于哪个环境
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
4.配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文
件
–file:./config/ 项目路径下的config文件夹配置文件
–file:./ 项目路径下配置文件
–classpath:/config/ 资源路径下的config文件夹配置文件
–classpath:/ 资源路径下配置文件
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;
我们在优先级最低的配置文件中配置 测试互补
server.port=8080
#配置项目的访问路径
server.servlet.context-path=/ka
因为我在优先级最高的配置文件下配置了端口号为8083
没有配置项目访问地址,用浏览器访问:localhost:8083/hello 出现404
我们加上配置的项目访问路径再进行访问localhost:8083/ka/hello 成功
扩展
我们可以指定位置加载配置文件
我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高
D:\workspace_idea\spring-boot-02\target>
java -jar spring-boot-02-0.0.1-SNAPSHOT.jar --spring.config.location=F:/application.properties
5.自动配置原理
官方配置属性参照:https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/htmlsingle/#core-properties
1.原理
1.SpringBoot 启动的时候会加载主配置类,并且开启著配置类的
@EnableConfiguration
2.进入@EnableConfiguration中可以看到
@EnableAutoConfiguration 开启自动配置
3.进入@EnableAutoConfiguration可以看到
@Import(AutoConfigurationImportSelector.class) 给ioc容器导入组件
AutoConfigurationImportSelector这个类中我们可以看到
selectImports()方法
这个方法中getCandidateConfigurations()获取候选配置
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
进入getCandidateConfigurations这个方法中
List<String> configurations =
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
进入loadFactoryNames()我们发现
扫描所有jar包类路径下 META‐INF/spring.factories
把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器
中
4.将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;
5.每一个着用xxxAutoConfiguration类都是容器中的一个 组件,都加入到容器中;用他们来做自动配置
6.每一个配置类进行自动配置功能
7.以HttpEncodingAutoConfiguration(Http自动编码配置)为例解释自动配置原理 进入到这个类中↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
/* @Configuration
* 表示这是一个Spring配置类,
* 类似于我们以前写的xml配置文件
*/
@Configuration(proxyBeanMethods = false)
/*
* @EnableConfigurationProperties(HttpProperties.class)
* 启动指定类的ConfigurationProperties功能
* 也就是将配置文件中的值与HttpProperties这个类中的属性绑定起来
* 并且把HttpProperties加入到ioc容器中
*/
@EnableConfigurationProperties(HttpProperties.class)
/*
*@ConditionalOnWebApplication
* Spring底层的@Conditional注解,根据不同条件来检查
* 如果满足指定条件,整个配置类里的配置就会生效
* 整个是判断是否为web应用,如果是就生效
*/
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
/*
* @ConditionalOnClass
* 判断当前项目有没有这个类
* CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
*/
@ConditionalOnClass(CharacterEncodingFilter.class)
/*
* 判断配置文件中是否存在某个配置
* spring.http.encoding.enabled;如果不存在,判断也是成立的
* 即使我们配置文件中不配置pring.http.encoding.enabled=true,
* 也是默认生效的;
*/
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
//获取和spring配置文件进行映射的properties类
private final HttpProperties.Encoding properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean//给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean//判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
}
根据个人理解
1.就是从META-INF/spring.factories
中获取xxxAutoConfiguration类,
自动装配类,如果我们需要改变自动装配类中的值,
我们就根据这个类绑定的properties类,在配置文件中修改
2.这个类中又绑定了xxxProperties类
这些组件的属性是从对应的properties类中获取的,
这些类里面的每一个属性又是和配置文件绑定的;
所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
配置文件能配置什么就可以参照某个功能对应的这个属性类
精髓:
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
2.细节
1、@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
自动配置类必须在一定的条件下才能生效;
我们怎么知道哪些自动配置类生效;
我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;