一、springboot项目中有两种配置文件

springboot项目中有两种配置文件 bootstrap 和 application

bootstrap是应用程序的父上下文,由父Spring ApplicationContext加载。所以加载顺序优先于application。

bootstrap 里面的属性不能被覆盖。

应用场景

  • bootstrap
  1. 使用 Spring Cloud Config 配置中心时,这时需要在bootstrap 配置文件中添加连接到配置中心的配置属性,来加载外部配置中心的配置信息
  2. 一些固定的不能被覆盖的属性
  3. 一些加密/解密的场景
  • application
  1. 主要用于 Spring Boot 项目的自动化配置

二、配置文件的使用

1、配置文件的书写小技巧

spring:
application:
name: @artifactId@
cloud:
nacos:
discovery:
server-addr: nacoshost:8848
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
autoconfigure:
exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration
profiles:
active: @profiles.active@

这段是配置文件内容:@artifactId@ 可以定位到pom 文件中的 <artifactId>pipe-server</artifactId>

          @profiles.active@ 可以定位到pom文件中的 <profiles.active>test</profiles.active>

server-addr: ${spring.cloud.nacos.discovery.server-addr}
这种写法 ${}定位的值就是本yml文件:server-addr: nacoshost:8848 这个地方

2、外部配置文件的引用以及多配置文件切换

  把外部链接地址放在bootstrap 文件里面 然后去读取文件 外部文件或者在服务器上,或者在git 通过nacos、spring cloud config、apollo 等等去找到外部文件然后读取。

1.多配置文件

  profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;

  例如:application-test.properties 代表测试环境配置    application-dev.properties 代表开发环境配置,但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;

  我们需要通过一个配置来选择需要激活的环境:在bootstrap中使用:spring.profiles.active=dev

3、读取配置文件内容

写个yml文件:

anything:
isok: true
sout: im.peizhi.wenjian
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*/
@Component //注册bean
@ConfigurationProperties(prefix = "anything")
public class Anything{
  private Boolean isok;
  private String sout ;
}

除了@ConfigurationProperties以外还可以使用@Value进行读取:

@Component //注册bean
public class Person {
//直接使用@value
@Value("${anything.isok}") //从配置文件中取值
  private Boolean isok;

@ConfigurationProperties是支持松散绑定的 松散绑定:比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定 ,@Value 不支持

@Value的其他使用方法:应该可以猜的看懂吧 不赘述了

@Component("role2")
public class Role2 {
//赋值long型
@Value("#{2}")
private Long id;
//字符串赋值
@Value("#{'role_name_2'}")
private String roleName;
//字符串赋值
@Value("#{'note_2'}")
private String note;
}
@Component("elBean")
public class ElBean {
//通过beanName获取bean,然后注入
@Value("#{role2}")
private Role2 role2;
//获取bean的属性id
@Value("#{role2.id}")
private Long id;
//调用bean的getNote方法,获取角色名称
// @Value("#{role.getNote().toString()}")
@Value("#{role2.getNote()?.toString()}")
private String note;
@Value("#{T(Math).PI}")
private double pi;
@Value("#{T(Math).random()}")
private double random;
@Value("#{role.id+1}")
private int num;
}

@PropertySource :加载指定的配置文件;

@PropertySource(value = "classpath:bootstrap.yml")
@Component //注册bean
public class Anything{
@Value("${anything.isok}")
private String name;
}

三、自动自动配置的原理

1.SpringBoot启动的时候加载主配置类,开启自动配置功能@EnableAutoConfig

2.@EnableAutoConfig作用:

  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件,导入了哪些组件呢?
  • 可以查看这个类selectImports()方法的内容,他返回了一个  autoConfigurationEntry , 来自  this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); 这个方法。我们继续跟踪;
  • 这个方法中有一个值 : List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); 叫做获取候选的配置 , 我们点击去继续跟踪;
  • 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.loadFactoryNames() ,我们继续进去看 , 它又调用了  loadSpringFactories 方法;继续跟踪。发现它去获得了一个资源文件:"META-INF/spring.factories"

  • Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
     

    继续阅读源码 , 它将读取到的资源封装在url中,然后遍历url , 将这些url文件封装在Properties文件中;最后返回封装好的结果;他的那个ClassLoader参数,我们追踪回去,看到他就是 EnableAutoConfiguration ;

  • 说明了这个逻辑就是 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

  • 总结一句话就是:将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;每一个 xxxAutoConfiguration类都是容器中的一个组件,最后都加入到容器中;用他们来做自动配置;

3.每一个自动配置类可以进行自动配置功能;

4.我们以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;

所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功能对应的这个属性类

@ConfigurationProperties( prefix = "spring.http" ) //从配置文件中获取指定的值和bean的属性进行绑定 在一次工作中我的书写是这样的(prefix = "tlyh.restUrl")报错格式不规范 应该改为:tlyh.rest-url
public class HttpProperties {
private boolean logRequestDetails;
private final HttpProperties.Encoding encoding = new HttpProperties.Encoding(); public HttpProperties() {
} public boolean isLogRequestDetails() {
return this.logRequestDetails;
} public void setLogRequestDetails(boolean logRequestDetails) {
this.logRequestDetails = logRequestDetails;
} public HttpProperties.Encoding getEncoding() {
return this.encoding;
} public static class Encoding {
public static final Charset DEFAULT_CHARSET;
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
}
}

5. 下面是自己写的HttpEncodingAutoConfiguration组件

@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
//启动指定类的ConfigurationProperties功能;
//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
//并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class}) //Spring底层@Conditional注解
//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
type = Type.SERVLET
) //判断当前项目有没有这个类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 { //他已经和SpringBoot的配置文件映射了
private final Encoding properties; //只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
} //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@Bean
@ConditionalOnMissingBean //判断容器没有这个组件?
public 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;
}
}

一句话总结 : 根据当前不同的条件判断,决定这个配置类是否生效!

一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;


这就是自动装配的原理!


精髓:


1)、SpringBoot启动会加载大量的自动配置类


2)、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;


3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)


4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;


xxxxAutoConfigurartion:自动配置类;给容器中添加组件


xxxxProperties:封装配置文件中相关属性;

@Conditional

了解完自动装配的原理后,我们来关注一个细节问题 ,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们怎么知道哪些自动配置类生效;我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#开启springboot的调试类 debug=true
 

关于spring boot项目配置文件的一些想法的更多相关文章

  1. spring boot项目配置文件集合

    表 1. Spring Boot 推荐的基础 POM 文件 名称 说明 spring-boot-starter 核心 POM,包含自动配置支持.日志库和对 YAML 配置文件的支持. spring-b ...

  2. 【Spring Boot】Spring Boot项目设置多个配置文件,并在生产环境中的Tomcat设置对应的配置文件

    1.修改Spring Boot项目配置文件 除了主配置文件,另外创建2个配置文件,注意命名要用application-*.properties 主配置文件中写入,使用dev作为开发配置 spring. ...

  3. [读书笔记] 一、Spring boot项目搭建与配置文件

    读书笔记:[JavaEE开发的颠覆者 Spring Boot实战] 作者:汪云飞 从今天开始坚持读书,并记录下此读书笔记. 一,初接触 Spring boot 项目Hello world搭建 1.po ...

  4. Spring Boot入门(一):使用IDEA创建Spring Boot项目并使用yaml配置文件

    由于公司最近在做技术转型(从.Net转Java),因此自己也开启了学习Java之路.学习Java怎么能不学习这几年这么火的Spring Boot框架,由于自己有总结的习惯,因此会把学习的过程以博客的形 ...

  5. spring boot 项目从配置文件中读取maven 的pom.xml 文件标签的内容。

    需求: 将pom.xml 文件中的版本号读取到配置文件并打印到日志中. 第一步: 在pom.xml 中添加以下标签. 第二步: 将version 标签的值读取到配置文件中 这里使用 @@  而不是  ...

  6. 用Gradle构建Spring Boot项目

    相比起Maven的XML配置方式,Gradle提供了一套简明的DSL用于构建Java项目,使我们就像编写程序一样编写项目构建脚本.本文将从无到有创建一个用Gradle构建的Spring Boot项目, ...

  7. spring boot项目如何测试,如何部署

    有很多网友会时不时的问我,spring boot项目如何测试,如何部署,在生产中有什么好的部署方案吗?这篇文章就来介绍一下spring boot 如何开发.调试.打包到最后的投产上线. 开发阶段 单元 ...

  8. 从零部署Spring boot项目到云服务器(正式部署)

    上一篇文章总结了在Linux云服务器上部署Spring Boot项目的准备过程,包括环境的安装配置,项目的打包上传等. 链接在这里:http://www.cnblogs.com/Lovebugs/p/ ...

  9. 后端开发实践——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

随机推荐

  1. 原创|我是如何从零学习开发一款跨平台桌面软件的(Markdown编辑器)

    原始冲动 最近一直在学习 Electron 开发桌面应用程序,目的是想做一个桌面编辑器,虽然一直在使用Typore这款神器,但无奈Typore太过国际化,在国内水土不服,无法满足我的一些需求. 比如实 ...

  2. Nmap强大在哪之主机发现

    1.概述 博主前段时间刚入坑渗透测试,随着学习的深入,越来越发现Nmap简直无所不能.今天先从主机发现功能入手分析. 2.Nmap主机发现 nmap --help #nmap帮助 3.参数分析 3.1 ...

  3. Spring源码分析之AOP

    1.AOP简介 AOP即面向切面编程(Aspect Oriented Programming),通过预编译方式及运行期动态代理实现程序功能的统一维护的一种技术.使用aop对业务逻辑的各个部分进行隔离, ...

  4. Xamarin.Forms学习系列之SQLite

    在App中我们通常不会实时获取服务器数据,会在用户手机中保存历史数据,这个时候就需要用到数据库SQLite,由于微软的封装,在Xamarin中操作SQLite非常简单,类似EF的操作. 1.我们需要在 ...

  5. Android Binder机制介绍

    做过Android开发的同学可能有些体会,入门初期,工作内容主要是实现各式各样的UI界面,以及实现应用的业务逻辑.在这个阶段,我们会逐渐熟悉View系统,逐渐学会实现各种各样的界面以及动画效果.再往后 ...

  6. FaceBook的秘钥散列获取

    随笔记录 先下载OpenSSL工具 在C盘创建一个openssl,将下好的OpenSSL工具解压到这里 将你的 .keystore文件复制到JAVA JDK 文件夹的bin目录里面(C:\Progra ...

  7. 行内元素(inline标签)设置了行高为什么不生效,还是表现为父盒子的行高?行内元素行高问题终极解释

    最近在看张鑫旭大佬的<css世界>,读到5.2.4  内联元素 line-height 的“大值特性” ,产生了疑惑, 在开发中确实也遇到了同样的问题,深入探究后得出结果,先说结论吧,论证 ...

  8. CSS浮动和各种定位

    CSS定位 css定位机制 文档流:元素按照在HTML中的位置决定排布的过程 块级元素是从上到下的,内联元素是从左到右的 浮动 position布局 position css position属性用于 ...

  9. shell脚本中的逻辑判断、文件目录属性判断、if特殊用法、case判断

    7月12日任务 20.5 shell脚本中的逻辑判断20.6 文件目录属性判断20.7 if特殊用法20.8/20.9 case判断 20.5 shell脚本中的逻辑判断 逻辑判断在shell中随处可 ...

  10. LNMP架构源码搭建(centos7)

    第一步:安装nginx 1.上传或下载nginx,并解压 yum -y install lrzsz rz .tar.gz 2.搭建nginx安装环境 yum -y install gcc-c++ zl ...