美文网首页Spring cloud程序员
(2) spring-boot配置详解

(2) spring-boot配置详解

作者: 桥头放牛娃 | 来源:发表于2018-10-26 18:13 被阅读12次

    Spring Boot简化了基于Spring的应用开发,其为spring及第三方平台提供开箱即用的设置,多数Spring Boot应用只需要很少的Spring配置。

    spring特性:

    • 为所有Spring开发提供一个从根本上更快,且随处可得的入门体验。
    • 开箱即用,但通过不采用默认设置可以快速摆脱这种方式。
    • 提供一系列大型项目常用的非功能性特征,比如:内嵌服务器,安全,指标,健康检测,外部化配置。
    • 绝对没有代码生成,也不需要XML配置。

    1、Spring-Boot核心配置文件

    SpringBoot配置文件可以使用yml格式和properties格式,分别的默认命名为:application.yml、application.properties

    配置.png

    1.1、存放目录

    • 项目根目录下
    • 项目根目录中config目录下
    • 项目的resources目录下
    • 项目resources目录中config目录下
    项目.png

    1.2、读取顺序

    如果在不同的目录中存在多个配置文件,它的读取顺序是:

    1. config/application.properties(项目根目录中config目录下)
    2. config/application.yml
    3. application.properties(项目根目录下)
    4. application.yml
    5. resources/config/application.properties(项目resources目录中config目录下)
    6. resources/config/application.yml
    7. resources/application.properties(项目的resources目录下)
    8. resources/application.yml

    注:

    1、如果同一个目录下,有application.yml也有application.properties,默认先读取application.properties。
    2、如果同一个配置属性,在多个配置文件都配置了,默认使用第1个读取到的,后面读取的不覆盖前面读取到的。
    3、创建SpringBoot项目时,一般的配置文件放置在“项目的resources目录下”
    

    1.3、更改默认配置文件位置

    如果不喜欢将application.properties作为配置文件名,你可以通过指定spring.config.name环境属性来切换其他的名称,也可以使用spring.config.location环境属性引用一个明确的路径(目录位置或文件路径列表以逗号分割)。

    $ java -jar myproject.jar --spring.config.name=myproject
    

    $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
    

    注意:

    (1)、在初期需要根据spring.config.name和spring.config.location决定加载哪个文件,所以它们必须定义为environment属性(通常为OS env,系统属性或命令行参数)。
    (2)、如果spring.config.location包含目录(相对于文件),那它们应该以/结尾(在被加载前,spring.config.name关联的名称将被追加到后面,包括profile-specific的文件名)。spring.config.location下定义的文件使用方法跟往常一样,没有profile-specific变量支持的属性,将被profile-specific的属性覆盖。
    (3)、不管spring.config.location配置什么值,默认总会按照classpath:,classpath:/config,file:,file:config/的顺序进行搜索,优先级由低到高,也就是file:config/获胜。如果你指定自己的位置,它们会优先于所有的默认位置(locations),并使用相同的由低到高的优先级顺序。那样,你就可以在application.properties为应用设置默认值,然后在运行的时候使用不同的文件覆盖它,同时保留默认配置。
    

    2、spring-boot读取配置

    spring-boot的核心配置文件为application.properties,同时也可通过注解自定义配置文件。

    2.1、使用@Value方式读取核心配置

    使用方法:

    @Value("${xxx}")

    使用示例:

    package Solin.controller;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class WebController {
      @Value("${test.msg}")
      private String msg;
    
      @RequestMapping("/index1")
      public String index1(){
        return "方式一:"+msg;
      }
    }
    

    注意事项:

    在@Value的${}中包含的是核心配置文件application.properties中的键名。
    

    2.1、使用Environment方式

    使用方法:
    用注入Environment实例,通过Environment.getProperty("xxx")获取配置信息;

    使用示例:

    package Solin.controller;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class WebController {
      @Autowired
      private Environment env;
    
      @RequestMapping("/index2")
      public String index2(){
        return "方式二:"+env.getProperty("test.msg");
      }
    }
    

    注意事项:

    (1)、这种方式是依赖注入Evnironment来完成,在创建的成员变量private Environment env上加上@Autowired注解即可完成依赖注入,然后使用env.getProperty("键名")即可读取出对应的值。
    (2)、Evnironment不仅能获取核心配置application.properties的参数,还能获取应用运行的一些环境参数,例如:env.getProperty("JAVA_HOME"),env.getProperty("CLASSPATH")等;
    

    2.3、使用@ConfigurationProperties读取

    @ConfigurationProperties可以读取核心配置application.properties中的配置,也可读取自定义的配置;

    使用方法:

    使用@Component及@ConfigurationProperties一起生成配置bean;若要读取自定义配置,则还需@PropertySource配合使用;

    使用示例:

    代码:

    @Component
    @ConfigurationProperties(value = "my")
    @PropertySource("classpath:config/myconfig.properties")
    
    public class TestConfigurationProperties {
    private String name;
    private int age;
    private String sex;
    
    //getter、setter方法
    }
    

    myconfig.properties配置:

    my.name = zhaozhou
    my.age = 20
    my.sex = man
    

    说明:

    • 示例中@ConfigurationProperties(value = "my"),设置属性组前缀,与@ConfigurationProperties(prefix= "my")等同;
    • @PropertySource(value="classpath:config/myconfig.properties")加载指定的属性文件,value设置自定义配置文件的位置,此配置可以放在此位置,也可放在其他位置;

    3、外化配置

    3.1、配置随机值

    在注入随机值(比如,密钥或测试用例)时RandomValuePropertySource很有用,它能产生整数,longs或字符串,比如:

    my.secret=${random.value}
    my.number=${random.int}
    my.bignumber=${random.long}
    my.number.less.than.ten=${random.int(10)}
    my.number.in.range=${random.int[1024,65536]}
    

    random.int*语法是OPEN value (,max) CLOSE,此处OPEN,CLOSE可以是任何字符,并且value,max是整数。如果提供max,那么value是最小值,max是最大值(不包含在内)。

    3.2、访问命令行属性

    默认情况下,SpringApplication会将所有命令行配置参数(以'--'开头,比如--server.port=9000)转化成一个property,并将其添加到Spring Environment中。正如以上章节提过的,命令行属性总是优先于其他属性源。如果不想将命令行属性添加到Environment,你可以使用SpringApplication.setAddCommandLineProperties(false)来禁用它们。

    3.3、Profile-specific属性

    除了application.properties文件,profile-specific属性也能通过命名惯例application-{profile}.properties定义。Environment(Spring的环境抽象接口)有个默认profiles集合(默认情况为[default]),在没有设置激活的profiles时会被使用(例如,如果没有明确指定激活的profiles,application-default.properties中的属性会被加载)。Profile-specific属性加载路径和标准的application.properties相同,并且profile-specific文件总是会覆盖non-specific文件,不管profile-specific文件是否被打包到jar中。如果定义多个profiles,最后一个将获胜。例如,spring.profiles.active定义的profiles被添加到通过SpringApplicationAPI定义的profiles后面,因此优先级更高。

    注意:如果你已经在spring.config.location下定义所有文件(非目录),那些profile-specific的文件将不被考虑。如果想使用profile-specific属性,那就在spring.config.location下使用目录。

    3.4、属性占位符

    当使用application.properties定义的属性时,Spring会先通过已经存在的Environment查找该属性,所以你可以引用事先定义的值(比如,系统属性):

    app.name=MyApp
    app.description=${app.name} is a Spring Boot application
    

    4、类型安全的配置属性

    4.1、第三方配置

    @ConfigurationProperties不仅可以注解在类上,也可以注解在public @Bean方法上,当你需要为不受控的第三方组件绑定属性时,该方法将非常有用。为了从Environment属性中配置一个bean,你需要使用@ConfigurationProperties注解该bean:

    @ConfigurationProperties(prefix = "foo") 
    @Bean public FooComponent fooComponent() {
       …… 
    }
    

    所有以foo为前缀的属性定义都会被映射到FooComponent上。

    4.2、Relaxed绑定

    Spring Boot将Environment属性绑定到@ConfigurationProperties beans时会使用一些宽松的规则,所以Environment属性名和bean属性名不需要精确匹配。常见的示例中有用的包括虚线分割(比如,context-path绑定到contextPath),将environment属性转为大写字母(比如,PORT绑定port)。

    例如,给定以下@ConfigurationProperties类:

    @ConfigurationProperties(prefix="person") 
    public class OwnerProperties { 
      private String firstName; 
      public String getFirstName() { 
        return this.firstName; 
      } 
      public void setFirstName(String firstName) { 
        this.firstName = firstName; 
      } 
    }
    

    下面的属性名都能使用:

    属性 说明
    person.firstName 标准驼峰规则
    person.first-name 虚线表示,推荐用于.properties和.yml文件中
    person.first_name 下划线表示,用于.properties和.yml文件的可选格式
    PERSON_FIRST_NAME 大写形式,使用系统环境变量时推荐

    4.3、属性转换

    将外部应用配置绑定到@ConfigurationProperties beans时,Spring会尝试将属性强制转换为正确的类型。如果需要自定义类型转换器,你可以提供一个ConversionService bean(bean id为conversionService),或自定义属性编辑器(通过CustomEditorConfigurer bean),或自定义Converters(bean定义时需要注解@ConfigurationPropertiesBinding)。

    注意:由于该bean在应用程序生命周期的早期就需要使用,所以确保限制你的ConversionService使用的依赖。通常,在创建时期任何你需要的依赖可能都没完全初始化。

    4.4、@ConfigurationProperties校验

    Spring Boot将尝试校验外部配置,默认使用JSR-303(如果在classpath路径中),你只需要将JSR-303 javax.validation约束注解添加到@ConfigurationProperties类上:

    @ConfigurationProperties(prefix="connection") 
    public class ConnectionProperties { 
      @NotNull 
      private InetAddress remoteAddress; 
    
      // ... getters and setters 
    }
    

    为了校验内嵌属性的值,你需要使用@Valid注解关联的字段以触发它的校验,例如:

    @ConfigurationProperties(prefix="connection") 
    public class ConnectionProperties { 
      @NotNull 
      @Valid 
      private RemoteAddress remoteAddress; 
      
      // ... getters and setters 
      public static class RemoteAddress { 
        @NotEmpty 
        public String hostname; 
        // ... getters and setters 
      } 
    }
    

    你也可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator。@Bean方法需要声明为static,因为配置属性校验器在应用程序生命周期中创建的比较早,将@Bean方法声明为static允许该bean在创建时不需要实例化@Configuration类,从而避免了早期实例化(early instantiation)的所有问题。

    4.5、@ConfigurationProperties与@Value对比

    @Value是Spring容器的一个核心特性,它没有提供跟type-safe Configuration Properties相同的特性。下面的表格总结了@ConfigurationProperties和@Value支持的特性:

    特性 @ConfigurationProperties @Value
    Relaxed绑定 Yes No
    Meta-data支持 Yes No
    SpEL表达式 No Yes

    如果你为自己的组件定义了一系列的配置keys,我们建议你将它们以@ConfigurationProperties注解的POJO进行分组。由于@Value不支持relaxed绑定,所以如果你使用环境变量提供属性值的话,它就不是很好的选择。最后,尽管@Value可以写SpEL表达式,但这些表达式不会处理来自Application属性文件的属性。

    5、profiles配置

    Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只在特定的环境下生效。任何@Component或@Configuration都能注解@Profile,从而限制加载它的时机:

    @Configuration @Profile("production") 
    public class ProductionConfiguration { 
      // ... 
    }
    

    以正常的Spring方式,你可以使用spring.profiles.active的Environment属性来指定哪个配置生效。你可以使用通常的任何方式来指定该属性,例如,可以将它包含到application.properties中:

    spring.profiles.active=dev,hsqldb
    

    或使用命令行开关:

    --spring.profiles.active=dev,hsqldb
    

    5.1、添加激活的配置(profiles)

    spring.profiles.active属性和其他属性一样都遵循相同的排列规则,优先级最高的PropertySource获胜,也就是说,你可以在application.properties中指定生效的配置,然后使用命令行开关替换它们。有时,将profile-specific的属性添加到激活的配置中而不是直接替换它们是有好处的。spring.profiles.include属性可以用来无条件的添加激活的配置,而SpringApplication的入口点也提供了一个用于设置其他配置的Java API,通过它设置的active配置优先级高于spring.profiles.active,具体参考setAdditionalProfiles()方法。

    例如,当一个应用使用下面的属性,并用--spring.profiles.active=prod开关运行,那proddb和prodmqprofiles也会激活:

    --- my.property: fromyamlfile 
    --- spring.profiles: prod spring.profiles.include: proddb,prodmq
    

    5.2、以编程方式设置profiles

    在应用运行前,你可以通过调用SpringApplication.setAdditionalProfiles(…)方法,以编程的方式设置激活的配置,也可以使用Spring的ConfigurableEnvironment接口激活配置(profiles)。

    5.3、Profile-specific配置文件

    Profile-specific的配置,不管是application.properties(或application.yml),还是通过@ConfigurationProperties引用的文件都是被当作文件来加载的。

    6、@import注解与@ImportResource注解

    • @Import注解就是之前xml配置中的import标签,可以用于依赖第三方包中bean的配置和加载
    • @ImportResource是引入spring配置文件.xml

    6.1、@import

    import注解主要用在基于java代码显式创建bean的过程中,用于将多个分散的java config配置类融合成一个更大的config类;

    代码示例:

    package com.yiibai.config;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    
    @Configuration
    @Import({ CustomerConfig.class, SchedulerConfig.class })
    public class AppConfig {
    }
    

    6.2、@ImportResource

    用于导入自定义的xml配置,相当于:

    <import resource="applicationContext-democonfig2.xml" />
    

    代码示例:

    @Configuration
    @ImportResource("classpath:applicationContext-democonfig2.xml")
    public class StoreConfig {
    
      @Value("${url}")
      private String url;
    
      @Value("${username}")
      private String username;
    
      @Value("${password}")
      private String password;
    
      @Bean
      public MyDriverManager myDriverManager() {
        return new MyDriverManager(url, username, password);
      }
    }
    

    XML代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.1.xsd">
    
    <context:property-placeholder location="classpath:config4.properties" />
    <context:component-scan base-package="com.dxz.imports4"></context:component-scan>
    </beans>
    

    <context:property-placeholder location="classpath:config4.properties" />用于指导资源文件位置。

    7、Java配置类

    Spring Boot提倡基于Java的配置。尽管你可以使用XML源调用SpringApplication.run(),不过还是建议你使用@Configuration类作为主要配置源。通常定义了main方法的类也是使用@Configuration注解的一个很好的替补。

    7.1、导入其他配置类

    你不需要将所有的@Configuration放进一个单独的类,@Import注解可以用来导入其他配置类。另外,你也可以使用@ComponentScan注解自动收集所有Spring组件,包括@Configuration类。

    7.2、导入XML配置

    如果必须使用XML配置,建议你仍旧从一个@Configuration类开始,然后使用@ImportResource注解加载XML配置文件。

    8、快速查阅

    相关阅读:
    spring-boot基础环境搭建 【https://www.jianshu.com/p/ee36bb9faa10
    spring-boot+druid+mybatis环境搭建【https://www.jianshu.com/p/e6c9e9945e45
    spring-boot+logback+log4j2+MDC【https://www.jianshu.com/p/51da61a425ba

    参考博客:
    https://blog.csdn.net/qq_32786873/article/details/52840745
    https://www.jianshu.com/p/60b34464ca58
    https://www.cnblogs.com/duanxz/p/3787757.html

    参考书籍:
    《Spring Boot参考指南》 (https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/III.%20Using%20Spring%20Boot/15.2.%20Importing%20XML%20configuration.html

    相关文章

      网友评论

        本文标题:(2) spring-boot配置详解

        本文链接:https://www.haomeiwen.com/subject/rolltqtx.html