有哪些外贸公司网站做的比较好,自己建设网站,清河做网站哪家好,网站模板源码下载网文章目录一、配置文件二、YAML语法1、基本语法2、值的写法(1)、字面量#xff1a;普通的值#xff08;数字#xff0c;字符串#xff0c;布尔#xff09;(2)、对象、Map#xff08;属性和值#xff09;(3)、数组#xff08;List、Set#xff09;三、配置文件值注入1、…
文章目录一、配置文件二、YAML语法1、基本语法2、值的写法(1)、字面量普通的值数字字符串布尔(2)、对象、Map属性和值(3)、数组List、Set三、配置文件值注入1、一个简单的示例2、Value获取值和ConfigurationProperties获取值比较3、数据校验4、使用PropertySource加载指定的配置文件5、使用ImportResource导入Spring的配置文件6、使用配置类及Bean注解来给容器添加组件四、配置文件占位符1、随机数2、占位符获取之前配置的值五、Profile1、多Profile文件2、yml支持多文档块形式3、激活指定Profile(1)、在配置文件中指定spring.profiles.active属性来激活(2)、使用命令行来激活3、虚拟机参数六、配置文件的加载位置七、外部配置加载顺序(1)、命令行参数(2)、关于jar包外、jar包内的配置文件以及带不带profiles的顺序区别(3)、Configuration注解类上的PropertySource八、SpringBoot配置的原理1、Springboot启动的时候加载主配置类时开启自动配置功能2、EnableAutoConfiguration作用3、每一个自动配置类进行自动配置4、我们以HttpEncodingAutoConfiguration为例来解释自动配置原理(1)、Configuration(2)、EnableConfigurationProperties(3)、ConditionalOnWebApplication(4)、ConditionalOnClass(5)、ConditionalOnProperty(6)、总结5、结论九、Conditional及其自动配置报告一、配置文件
springboot使用一个全局的配置文件配置文件名是固定的一般有两种写法
application.propertiesapplication.yml
配置文件的作用SpringBoot在底层都给我们自动配置了而配置文件的作用就是修改SpringBoot自动配置的默认值。
之前的配置文件都是使用的xml文件格式但是YAML也可以做配置文件YAML是以数据为中心比JSON、XML等等更适合做配置文件。 配置示例将端口号设置为8081
server:port: 8081二、YAML语法
1、基本语法
k: v:表示一对键值对空格必须有。以空格的缩进来控制层级关系只要是左对齐的一列数据都是同一个层级的。并且其属性和值都是大小写敏感的。
示例
server:port: 8081path: /hello2、值的写法
(1)、字面量普通的值数字字符串布尔
使用k: v: 对于字符串默认不用加上单引号或者双引号双引号不会转义字符串里面的特殊字符特殊字符会作为本身想表示的意思单引号就会转义字符特殊字符最终只是一个普通的字符串数据。
(2)、对象、Map属性和值
还是使用k:v:方式在下一行来写对象的属性和值的关系注意缩进例如
friend:lastName: zhangsanage: 20这样表示lastName和age是friend对象的属性。 也可以写成行内写法friend: {lastName: zhangsan,age: 18}
(3)、数组List、Set
用-表示数组中的一个元素
pets:- cat,- dog,- pig也可以写成pets: [cat,dog,pig] 三、配置文件值注入
在JavaBean类中加入ConfigurationProperties注解将配置文件中配置的每一个属性的值映射到这个组件中并且要将这个类加入到IOC容器中。要注意的是ConfigurationProperties默认是从全局配置文件中获取值的。
1、一个简单的示例
yml文件
person:lastName: zhangsanage: 18boss: falsebirth: 2019/12/12map: {k1: 1,k2: 2}list:- lisi- zhaoliudog:name: 小狗age: 2JavaBean省略getter、setter、toString方法
package com.cerr.springboot.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/*** 将配置文件中配置的每一个属性的值映射到这个组件中* ConfigurationProperties告诉Springboot将本类中的所有属性和配置文件中相关的配置进行绑定* prefix配置文件中哪个下面的所有属性进行配置** 只有这个组件是容器中的组件才能使用容器提供的ConfigurationProperties功能*/
Component
ConfigurationProperties(prefix person)
public class Person {private String lastName;private Integer age;private Boolean boss;private Date birth;private MapString,Object map;private ListObject list;private Dog dog;
}我们可以导入配置文件处理器以后编写配置就有提示 !-- 导入配置文件处理器配置文件进行绑定就会有提示 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependency刚刚在yml中的配置也可以在properties中配置
person.last-name张三
person.age14
person.birth2019/12/2
person.bossfalse
person.map.k111
person.map.k222
person.lista,b,c
person.dog.namedog
person.dog.age152、Value获取值和ConfigurationProperties获取值比较
对于yml或者properties配置文件这两个注解都可以获取到配置文件的值但是它们有以下的区别
ConfigurationPropertiesValue功能批量注入配置文件中的属性必须一个一个属性的指定松散语法松散绑定支持不支持SpEL不支持支持JSR303数据校验支持不支持复杂类型封装支持不支持
如果我们只是在某个业务逻辑中需要获取一下配置文件的某个值时我们使用Value比较方便如果我们专门编写了一个JavaBean来和配置文件进行映射我们就直接使用ConfigurationProperties。
3、数据校验
在类上标注Validated注解并在你需要校验的字段标注上对应的注解即可假设我们在lastName字段要使用Eamil校验则代码如下
Component
ConfigurationProperties(prefix person)
Validated
public class Person {Emailprivate String lastName;private Integer age;private Boolean boss;private Date birth;private MapString,Object map;private ListObject list;private Dog dog;
}4、使用PropertySource加载指定的配置文件
PropertySource这个注解可以加载指定的配置文件。 我们定义一个局部的配置文件文件的位置位于类路径下如图所示 使用PropertySource(value {classpath:person.properties})将该配置文件加载进来
PropertySource(value {classpath:person.properties})
Component
ConfigurationProperties(prefix person)
Validated
public class Person {private String lastName;private Integer age;private Boolean boss;private Date birth;private MapString,Object map;private ListObject list;private Dog dog;
}
5、使用ImportResource导入Spring的配置文件
ImportResource的作用是导入Spring的配置文件让配置文件里面的内容生效。
我们编写了一个spring的配置文件位于类路径下
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdbean classcom.cerr.springboot.service.HelloService idhelloService/bean
/beans
然后我们在Spring的单元测试中测试ioc容器中是否有helloService这个bean
SpringBootTest
class Springboot01DemoApplicationTests {AutowiredApplicationContext ioc;Testpublic void testHelloService(){boolean b ioc.containsBean(helloService);System.out.println(b);}
}
结果却是没有这个bean因为此时这个配置文件并没有被加载因此我们需要使用ImportResource注解让该文件加载进来在主配置类中我们使用该注解
//导入Spring的配置文件并让其生效
ImportResource(locations {classpath:bean.xml})
SpringBootApplication
public class Springboot01DemoApplication {public static void main(String[] args) {SpringApplication.run(Springboot01DemoApplication.class, args);}
}
然后我们再一次在Spring的单元测试中测试现在结果是有包含这个bean。
但是我们不推荐这种形式来给容器添加组件Spring比较推荐使用以下这种方式
6、使用配置类及Bean注解来给容器添加组件
Spring比较推荐使用配置类来给容器添加组件首先我们先定义一个配置类
package com.cerr.springboot.config;
import com.cerr.springboot.service.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*** 指明当前类是一个配置类用来替代之前的Spring配置文件*/
Configuration
public class AppConfig {//将方法的返回值添加到容器中容器中这个组件默认的id就是方法名Beanpublic HelloService helloService(){System.out.println(给容器中添加组件了);return new HelloService();}
}该配置类使用了Configuration注解表示其是一个配置类然后在方法中使用了Bean注解该注解的作用是将方法的返回值添加到ioc容器中并且这个组件的id就是方法名。 我们还是使用刚刚的那个测试类来测试ioc容器中是否包含了这个bean 四、配置文件占位符
1、随机数
例如在配置文件中给lastName和age字段加上随机数
person.last-name张三${random.uuid}
person.age${random.int}
2、占位符获取之前配置的值
person.last-name张三${random.uuid}
person.dog.name${person.last-name:hello}_dogperson.dog.name的值就是person.last-name的值拼上_dog然后后面的:hello的意思是如果我们没有在配置文件中指定person.last-name的值那么那个占位符的默认值就是hello。 五、Profile
1、多Profile文件
我们在编写主配置文件的时候文件名可以是application-{profile}.properties/yml默认使用application.properties文件的配置。
我们新建了application-dev.properties,application-prod.properties文件分别指定其port为8083和80然后在application.properties文件中
server.port8080
spring.profiles.activedev第一句表示默认的环境配置没指定是哪种环境时为端口号是8080第二句表示指定dev环境即使用我们配置的application-dev.properties文件。
2、yml支持多文档块形式
yml中使用---可以将文件分为多文档在不同的文档中定义即可
server:port: 8081path: /hello
spring:profiles:active: dev
---
server:port: 8083
spring:profiles: dev---
server:port: 80
spring:profiles: prod上述代码中在文档2中我们定义了dev环境下的配置文档3中定义了prod环境下的配置然后在文档1中我们先定义了默认的配置并且使用了如下格式来配置环境
spring:profiles:active: dev因此当前使用的环境是dev环境所以此时的端口号应该是8083我们启动主启动类 3、激活指定Profile
(1)、在配置文件中指定spring.profiles.active属性来激活
对于properties文件我们可以这样激活
spring.profiles.activedev(2)、使用命令行来激活
在终端中使用--spring.profiles.activexxx来激活比如我们在配置yml配置文件中指定激活dev环境
server:port: 8081path: /hello
spring:profiles:active: dev但是我们在idea中加上命令行参数--spring.profiles.activeprod表示我们想激活prod环境 最后启动之后发现使用的是prod的环境配置 或者是将项目打包为jar包后在终端中运行该jar包且指定命令行参数也行
命令行输入
java -jar springboot-01-demo-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod3、虚拟机参数
在IDEA中设置虚拟机参数-Dspring.profiles.activeprod 然后启动 六、配置文件的加载位置
Springboot启动会扫描以下位置的application.properties或者application.yml文件作为Springboot的默认配置文件
file:../config/根目录下的config文件夹下file:../根目录下classpath:/config/类路径下的config文件夹下classpath:/类路径下
以上是按照优先级从高到低的顺序所有位置的文件都会被加载高优先级配置内容会覆盖低优先级配置内容称为互补配置。
例如我们在根目录下新建一个config文件夹并且新建一个application.properties文件配置port为8082
server.port8082
在类路径下的application.properties文件中配置如下
server.port8081#配置项目的访问路径
server.servlet.context-path/boot1
因为配置文件遵循高优先级配置内容覆盖低优先级配置内容所以这类路径下文件的port配置会被第一个文件覆盖而第一个文件都没配置server.servlet.context-path所以这个属性的值还是第二个配置文件的值我们访问后 我们可以通过配置spring.config.location来改变默认配置 在项目打包好后我们可以使用命令行参数的形式启动项目的时候来指定配置文件得新位置。
我们在E盘中新建一个application.properties文件然后设置port为80
server.port80我们将项目打包后在IDEA的控制台中运行该jar包 默认端口为80因此localhost会省略80 七、外部配置加载顺序
Springboot可以从以下位置加载配置优先级从高到低高优先级的配置覆盖低优先级的配置
(1)、命令行参数
语法--配置项值多个参数使用空格分隔
打包后并在命令行输入
java -jar springboot-01-demo-0.0.1-SNAPSHOT.jar --server.port8087
运行jar包并且修改server.port8087启动后访问8087端口能正常运行访问原来的8082端口不能用 (2)、关于jar包外、jar包内的配置文件以及带不带profiles的顺序区别
由jar包外向jar包内进行寻找优先加载带profiles再来加载不带profiles
此时我们项目内配置文件最高优先级的应该是端口为8082我们将项目打包然后新建一个boot文件夹将打包好的jar包放入文件夹中 然后我们在该文件夹下新建一个application.properties文件在jar包外里面的配置如下
server.port8089在命令行中输入
java -jar springboot-01-demo-0.0.1-SNAPSHOT.jar此时的端口号为8089因此证明了我们定义在jar包外的这个配置文件是最高优先级的我们访问 因为访问的路径中有/boot2因此说明我们jar包内定义的配置文件也有起作用只是有一部分被jar包外的覆盖而已。
(3)、Configuration注解类上的PropertySource 八、SpringBoot配置的原理
1、Springboot启动的时候加载主配置类时开启自动配置功能
主配置类中有EnableAutoConfiguration注解我们下面来研究其作用
2、EnableAutoConfiguration作用
利用AutoConfigurationImportSelector给容器中导入一些组件。可以查看selectImports()的内容 public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationMetadata autoConfigurationMetadata AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} else {AnnotationAttributes attributes this.getAttributes(annotationMetadata);ListString configurations this.getCandidateConfigurations(annotationMetadata, attributes);configurations this.removeDuplicates(configurations);SetString exclusions this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations this.filter(configurations, autoConfigurationMetadata);this.fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);}}在selectImports方法中调用了getAutoConfigurationEntry()其方法中的一句代码List configurations this.getCandidateConfigurations(annotationMetadata, attributes);是获取候选的配置我们进入该方法 protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {ListString 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;}
该方法扫描所有jar包类路径下META-INF/spring.factories文件并把扫描到的这些文件的内容包装成properties对象。从properties中获取到EnableAutoConfiguration.class类名对应的值然后把他们添加到容器中。
总结来说其作用就是将类路径下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中 每一个xxxAutoConfiguration类都是容器中的一个组件都加入到容器中用他们来做自动配置。
3、每一个自动配置类进行自动配置
4、我们以HttpEncodingAutoConfiguration为例来解释自动配置原理
首先这个类上有如下的注解
Configuration(proxyBeanMethods false
)
EnableConfigurationProperties({HttpProperties.class})
ConditionalOnWebApplication(type Type.SERVLET
)
ConditionalOnClass({CharacterEncodingFilter.class})
ConditionalOnProperty(prefix spring.http.encoding,value {enabled},matchIfMissing true
)我们来逐一分析这些注解
(1)、Configuration
表示这是一个配置类。和以前编写的配置文件一样也可以给容器添加组件
(2)、EnableConfigurationProperties
这个注解表示启动指定类的ConfigurationProperties功能我们点进去HttpProperties类有如下注解
ConfigurationProperties(prefix spring.http
)
public class HttpProperties{
}ConfigurationProperties注解的作用是从配置文件中获取指定的值和bean的属性来进行绑定。
因此所有在配置文件中能配置的属性都是在xxxProperties类中封装着如果我们想要知道该配置文件能够配置什么功能我们就可以参考某个功能对应的Properties类
对于这个例子我们这个注解最后就是让配置文件中对应的值和HttpProperties绑定起来了并加入到ioc容器中为后面我们要向容器中添加组件服务。
(3)、ConditionalOnWebApplication
在Spring底层中有一个Conditional注解判断如果满足指定的条件整个配置类里面的配置会生效。 因此这个ConditionalOnWebApplication就是判断当前应用是否是web应用如果是则当前配置类生效。
(4)、ConditionalOnClass
判断当前项目有没有这个类。 ConditionalOnClass({CharacterEncodingFilter.class})表示判断当前项目中有没有CharacterEncodingFilter这个类这个类是SpringMVC中进行乱码解决的过滤器。
(5)、ConditionalOnProperty
判断配置文件中是否存在某个配置在这个例子中
ConditionalOnProperty(prefix spring.http.encoding,value {enabled},matchIfMissing true
)表示判断配置文件夹是否有spring.http.encoding.enabled这个配置而matchIfMissing true表示如果不存在这个配置这个配置也是默认生效的。
(6)、总结
因此AutoConfiguration配置类的作用就是不断的判断最终决定这个配置类是否生效如果生效的话则给容器添加各种组件这些组件的属性是从对应的properties类中获取的这些类里面的每一个属性又是和配置文件绑定的
HttpEncodingAutoConfiguration类中的一部分源码如下
public class HttpEncodingAutoConfiguration {//通过EnableConfigurationProperties注解和SpringBoot的配置文件进行了映射private final Encoding properties;//只有一个有参构造器的情况下参数的值就会从容器中拿public HttpEncodingAutoConfiguration(HttpProperties properties) {this.properties properties.getEncoding();}BeanConditionalOnMissingBeanpublic CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter new OrderedCharacterEncodingFilter();filter.setEncoding(this.properties.getCharset().name());filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));return filter;}
}5、结论
SpringBoot启动会加载大量的自动配置类。我们看我们需要的功能有没有SpringBoot默认写好的自动配置类我们再来看这个自动配置类中配置了哪些组件如果我们要用的组件有那我们就不需要再来配置给容器中自动配置类添加属性的时候会从properties类中获取某些属性我们就可以在配置文件中指定这些属性的值本质上SpringBoot的各种Properties类就封装了配置文件中的相关属性然后各种AutoConfiguration自动配置类就会给容器添加各种组件。 九、Conditional及其自动配置报告
Conditional作用必须是Conditional指定的条件成立才给容器中添加组件配置配里面的所有内容才生效
Conditional扩展注解作用判断是否满足当前指定条件ConditionalOnJava系统的java版本是否符合要求ConditionalOnBean容器中存在指定BeanConditionalOnMissingBean容器中不存在指定BeanConditionalOnExpression满足SpEL表达式指定ConditionalOnClass系统中有指定的类ConditionalOnMissingClass系统中没有指定的类ConditionalOnSingleCandidate容器中只有一个指定的Bean或者这个Bean是首选BeanConditionalOnProperty系统中指定的属性是否有指定的值ConditionalOnResource类路径下是否存在指定资源文件ConditionalOnWebApplication当前是web环境ConditionalOnNotWebApplication当前不是web环境ConditionalOnJndiJNDI存在指定项
自动配置类必须在一定的条件下才能生效 我们可以通过设置debugtrue属性来让控制台打印自动配置报告我们通过配置报告就知道哪些自动配置生效。