济宁网站建设软件,徐州赶集网招聘信息,李宁运动服网站建设规划书,ps做素材下载网站本篇要点介绍各种配置方式的优先级。介绍各种外部化配置方式。介绍yaml的格式及原理。介绍如何绑定并测试类型安全的属性配置。介绍ConfigurationProperties与Value的区别。一、SpringBoot官方文档对于外部化配置的介绍及作用顺序SpringBoot支持多种外部化配置#xff0c;以便…本篇要点介绍各种配置方式的优先级。介绍各种外部化配置方式。介绍yaml的格式及原理。介绍如何绑定并测试类型安全的属性配置。介绍ConfigurationProperties与Value的区别。一、SpringBoot官方文档对于外部化配置的介绍及作用顺序SpringBoot支持多种外部化配置以便于开发者能够在不同的环境下使用同一套应用程序代码。外部化配置的方式有多种properties文件yaml文件Environment变量已经命令行参数等等。外部化配置的属性值可以通过Value注解自动注入亦可以通过Spring的Environment抽象访问也可以通过ConfigurationProperties注解绑定到结构化对象上。SpringBoot支持很多种的外部化配置待会我们会介绍到。在这之前我们必须要知道如果多种配置同时出现一定是按照特定的顺序生效的。规则如下devtool处于active状态时 $HOME/.config/spring-boot 目录中的Devtool全局配置。测试中的TestPropertySource注解。测试中的SpringBootTest#properties注解特性。命令行参数。SPRING_APPLICATION_JSON 中的属性(环境变量或系统属性中的内联JSON嵌入)。ServletConfig 初始化参数。ServletContext 初始化参数。java:comp/env 里的JNDI属性JVM系统属性 System.getProperties() 。操作系统环境变量仅具有 random.* 属性的 RandomValuePropertySource 。应用程序以外的application-{profile}.properties或者application-{profile}.yml文件打包在应用程序内的application-{profile}.properties或者application-{profile}.yml文件应用程序以外的application.properties或者appliaction.yml文件打包在应用程序内的application.properties或者appliaction.yml文件Configuration类上的PropertySource注解需要注意在ApplicationContext刷新之前是不会将这个类中的属性加到环境中的像 logging.*,spring.main.* 之类的属性在这里配置为时已晚。默认属性(通过 SpringApplication.setDefaultProperties 指定).这里列表按组优先级排序也就是说 任何在高优先级属性源里设置的属性都会覆盖低优先级的相同属性 列如我们上面提到的命令行属性就覆盖了application.properties的属性。举个例子吧如果在application.properties中设置 name天乔巴夏 此时我用命令行设置 java -jar hyh.jar --author.namesummerday 最终的name值将会是summerday因为命令行属性优先级更高。二、各种外部化配置举例1、随机值配置配置文件中 ${random} 可以用来生成各种不同类型的随机值从而简化了代码生成的麻烦例如 生成 int 值、long 值或者 string 字符串。原理在于 RandomValuePropertySource 类重写了 getProperty 方法判断以 random. 为前缀之后进行了适当的处理。my.secret${random.value}my.number${random.int}my.bignumber${random.long}my.uuid${random.uuid}my.lessThanTen${random.int(10)}my.inRange${random.int[1024,65536]}2、命令行参数配置默认情况下SpringApplication将所有的命令行选项参数【以 -- 开头的参数如 --server.port9000 】转换为属性并将它们加入SpringEnvironment中命令行属性的配置始终优先于其他的属性配置。如果你不希望将命令行属性添加到Environment中可以使用 SpringApplication.setAddCommandLineProperties(false) 禁用它。$ java -jar app.jar --debugtrue #开启debug模式这个在application.properties文件中定义debugtrue是一样的3、属性文件配置属性文件配置这一部分是我们比较熟悉的了我们在快速创建SpringBoot项目的时候默认会在resources目录下生成一个application.properties文件。SpringApplication都会从配置文件加载配置的属性并最终加入到Spring的Environment中。除了resources目录下还有其他路径SpringBoot默认是支持存放配置文件的。/config/config以上四个优先级从上往下依次降低也就是说如果同时出现上面配置的属性将会覆盖下面的。关于配置文件properties和yaml文件都能够满足配置的需求。当然这些配置都是灵活的如果你不喜欢默认的配置文件命名或者默认的路径你都可以进行配置$ java -jar myproject.jar --spring.config.namemyproject$ java -jar myproject.jar --spring.config.locationclasspath:/default.properties,classpath:/override.properties4、指定profile属性通常情况下我们开发的应用程序需要部署到不同的环境下属性的配置自然也需要不同。如果每次在发布的时候替换配置文件过于麻烦。SpringBoot的多环境配置为此提供了便利。具体做法如下我们之前在介绍各种配置的优先级的时候说过 application-{profile}.properties或者application-{profile}.yml文件 的优先级高于 application.properties或application.yml 配置这里的profile就是我们定义的环境标识我们在resource目录下创建三个文件application.properties默认的配置default。application-dev.properties开发环境dev。application-prod.properties生产环境prod。我们可以通过指定 spring.profiles.active 属性来激活对应的配置环境spring.profiles.activedev或使用命令行参数的配置形式$ java -jar hyh.jar --spring.profiles.activedev如果没有profile指定的文件于profile指定的文件的配置属性同时定义那么指定profile的配置优先。5、使用占位符在使用application.properties中的值的时候他们会从Environment中获取值那就意味着可以引用之前定义过的值比如引用系统属性。具体做法如下name天乔巴夏description${name} is my name6、加密属性Spring Boot不提供对加密属性值的任何内置支持但是它提供了 修改Spring环境中的值 所必需的挂钩点。我们可以通过实现EnvironmentPostProcessor接口在应用程序启动之前操纵Environment。可以参考 howto.html 查看具体使用方法。7、使用YAML代替propertiesYAML是JSON的超集是一种 指定层次结构配置数据的便捷格式 我们以properties文件对比一下就知道了#propertiesspring.datasource.driver-class-namecom.mysql.cj.jdbc.Driverspring.datasource.urljdbc:mysql://localhost:3306/test?serverTimezoneGMT%2B8spring.datasource.usernamerootspring.datasource.password123456my.servers[0]www.hyh.commy.servers[1]www.yhy.com# ymlspring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?serverTimezoneGMT%2B8 username: root password: 123456my: server: - www.hyh.com - www.yhy.com只要在类路径上具有SnakeYAML库SpringApplication类就会自动支持YAML作为属性配置的方式。SpringBoot项目中的 spring-boot-starter 已经提供了相关类库 org.yaml.snakeyaml因此SpringBoot天然支持这种方式配置。关于yaml文件的格式可以参考官方文档 Using YAML Instead of Properties8、类型安全的属性配置上面说到通过 Value(${property}) 注解来注入配置有时会比较麻烦特别是当多个属性本质上具有层次结构的时候。SpringBoot提供了一种解决方案 让强类型的bean管理和验证你的配置 。直接来看具体的使用叭ConfigurationPropertie定义一个绑定配置的JavaBean使用默认构造器getter和setter注入ConfigurationProperties(acme)public class AcmeProperties { private boolean enabled; //acme.enabled 默认为false private InetAddress remoteAddress;// acme.remote-address 可以从String转换而来的类型 private final Security security new Security();//.. 省略getter和setter方法 public static class Security { private String username; // acme.security.username private String password; // acme.security.password private List roles new ArrayList(Collections.singleton(USER));// acme.security.roles//.. 省略getter setter方法 }}这种方式依赖于默认的空构造函数通过getter和setter方法赋值因此getter和setter方法是必要的且不支持静态属性的绑定。如果嵌套pojo属性已经被初始化值 private final Security security new Security(); 可以不需要setter方法。如果希望绑定器使用其默认构造函数动态创建实例则需要setter。通过ContructorBinding注解使用构造器绑定的方式ConstructorBinding //标注使用构造器绑定ConfigurationProperties(acme)public class AcmeProperties { private final Security security; private final boolean enabled; private final InetAddress remoteAddress; public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) { this.enabled enabled; this.remoteAddress remoteAddress; this.security security; } //..省略getter方法 ToString public static class Security { private final String username; private final String password; private final List roles; public Security(String username, String password, DefaultValue(USER) List roles) { this.username username; this.password password; this.roles roles; } } //..省略getter方法}如果没有配置Security实例属性那么最后结果Securitynull。如果我们想让Security{usernamenull,passwordnull,roles[USER]}可以在Security上加上DefaultValue。 public AcmeProperties(boolean enabled, InetAddress remoteAddress, DefaultValue Security security)通过EnableConfigurationProperties注册已经定义好了JavaBean并与配置属性绑定完成接着需要注册这些bean。我们通常用的Component或BeanImport加载bean的方式在这里是不可取的SpringBoot提供了解决方案 使用EnableConfigurationProperties 我们既可以一一指定配置的类也可以按照组件扫描的方式进行配置。SpringBootApplicationEnableConfigurationProperties({HyhConfigurationProperties.class, MyProperties.class,AcmeProperties.class})public class SpringBootProfileApplication {}SpringBootApplicationConfigurationPropertiesScan({com.hyh.config})public class SpringBootProfileApplication {}配置yaml文件acme: remote-address: 192.168.1.1 security: username: admin roles: - USER - ADMIN注入properties测试Configurationpublic class Application implements CommandLineRunner { Autowired private AcmeProperties acmeProperties; Override public void run(String... args) throws Exception { System.out.println(acmeProperties); }}//输出 AcmeProperties(securityAcmeProperties.Security(usernameadmin, passwordnull, roles[USER, ADMIN]), enabledfalse, remoteAddress/192.168.1.1)宽松绑定SpringBoot采用宽松的规则进行Environment和ConfigurationProperties标注bean的匹配。如ConfigurationProperties(prefixacme.my-project.person)public class OwnerProperties { private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName firstName; }}下面表格中的属性名都可以匹配ConfigurationProperties注解中的prefix值必须是kebab case形式的以 - 为分割符。Spring官方建议属性尽可能以lower-case kebab的形式my.property-nameacmeMap如何绑定绑定到Map属性时如果key包含 小写字母数字字符或-以外的任何其他字符 则需要使用方括号包围key以便保留原始值。 如果键没有被 [] 包围则所有非字母数字或-的字符都将被删除。如下hyh: username: 天乔巴夏 password: 123456 map: [/key1]: value1 #用引号包围[]用[]包围key /key3: value3 key-4: value4 key/5: value5# 结果map:{/key1value1,key5value5, key-4value4, key3value3}环境变量如何绑定遵循三条原则把 . 换成下划线 _ 。移除 - 。小写转大写。如 spring.main.log-startup-info 转为 SPRING_MAIN_LOGSTARTUPINFO my.acme[0].other 转为 MY_ACME_0_OTHER 。9、复杂类型之前介绍yml文件介绍了单纯的数组形式或值的绑定SpringBoot还支持复杂类型的绑定。merge: list: - name: 天乔巴夏 desc: 帅啊 - name: tqbx desc: 很帅啊 map: key1: name: summerday desc: handsome! key2: name: summerToStringConfigurationProperties(prefix merge)public class MergeProperties { private final List list new ArrayList(); private final Map map new HashMap(); public List getList() { return list; } public Map getMap() { return map; }}最后输出MergeProperties( list[User(name天乔巴夏, desc帅啊), User(nametqbx, desc很帅啊)], map{key1User(namesummerday, deschandsome!), key2User(namesummer, descnull)}a)10、参数校验对ConfigurationProperties类使用Spring的 Valid 注解时Spring Boot就会尝试对其进行验证。你可以直接在配置类上使用JSR-303 javax.validation 约束注解。这个做法的前提是你的类路径上有兼容的JSR-303实现org.hibernate hibernate-validator 6.0.18.Final然后将约束注解加到字段上如下DataValidatedConfigurationProperties(prefix validate)public class ValidateProperties { NotNull private String name; Valid private final SubProperties subProperties new SubProperties(); Data public static class SubProperties { Min(value 10,message 年龄最小为10) public Integer age; }}配置如下validate: name: hyh sub-properties: age: 5结果如下Description:Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under validate to com.hyh.config.ValidateProperties failed: Property: validate.sub-properties.age Value: 5 Origin: class path resource [application.yml]:47:10 Reason: 年龄最小为10 Action:Update your applications configuration三、ConfigurationProperties与Value的区别Value注解是一个核心容器功能它没有提供和type-safe配置属性相关的功能下面这个表格总结了两者分别支持的功能官方建议如果你为自己的组件定义了一套配置建议使用ConfigurationProperties和POJO绑定这样做能够提供结构化且类型安全的对象。如果硬要使用Value建议使用kebab-case形式如Value( ${demo.item-price})来源https://www.tuicool.com/articles/uQFFBzz