• 【spring boot】SpringBoot初学(2.1)


    前言

      算是对《SpringBoot初学(2) - properties配置和读取》的总结吧。

    概念性总结

      一、Spring Boot允许外化(externalize)你的配置。可以使用properties文件,YAML文件,环境变量和命令行参数来外化配置。

        使用@Value注解,可以直接将属性值注入到你的beans中,并通过Spring的Environment抽象或绑定到结构化对象来访问。

      二、Spring Boot使用一个非常特别的PropertySource次序来允许对值进行合理的覆盖,需要以下面的次序考虑属性:

        (尽量能理解了加载顺序在记忆,不强求记住。)
        1. 命令行参数
        2. 来自于java:comp/env的JNDI属性
        3. Java系统属性(System.getProperties())
        4. 操作系统环境变量
        5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
        6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
        7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
        8. 在@Configuration类上的@PropertySource注解
        9. 默认属性(使用SpringApplication.setDefaultProperties指定)

      三、YAML相对properties的缺点

        YAML文件不能通过@PropertySource注解加载。所以,在这种情况下,如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件。

      四、Spring boot类型安全的配置属性

        在spring提供的读取properties中,运用注解@Value("${property}")注解注入配置属性有时可能比较笨重,特别是需要使用多个properties或你的数据本身有层次结构。

        为了控制和校验你的应用配置,Spring Boot提供一个允许强类型beans的替代方法来使用properties。

        当@EnableConfigurationProperties注解应用到你的@Configuration时,任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。

        这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。

      五、Spring boot的松散绑定

        (摘自:spring boot参考指南,101/420,23.7.2)

        image

        (暂时也没理解ConversionService到底要怎么写。)

     

    一、java基本类型的properties读取

      java的8种基本类型:逻辑型boolean、文本型char、整数型(byte、short、int、long)、浮点型(float、double)。对应的封装类型如Integer、Boolean等是一样的。

      特殊类型String。

    ## BaseProperty.properties
    byte_=1
    short_=2
    int_=23
    long_=1234
    float_=123.456
    double_=12345.6789
    char_=2
    boolean_=true
    ## 中文乱码问题,不同的IDE问题处理不一样。
    string_=str中文
    ## 日期不知如何直接注入成Date类型
    date_=2017-02-13
    package com.vergilyn.demo.springboot.properties.bean;
    
    import javax.validation.constraints.NotNull;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    @Configuration
    @ConfigurationProperties()
    @PropertySource("classpath:config/properties/BaseProperty.properties")
    @Component
    public class BasePropertyBean {
    	private byte byte_ ;
    	private short short_ ;
    	private int int_ ;
    	private long long_ ;
    	private float float_ ;
    	private double double_ ;
    	private char char_ ;
    	private boolean boolean_ ;
    	@NotNull	//加JSR-303 javax.validation约束注解
    	private String string_;
    	/* 不知道怎么直接注入Date类型*/
    //	private Date date_;
    
    	// 省略set/get
    
    }
    

    二、复杂类型

      如Map,List,数组等。

    ## ComplexProperty.properties
    ## map
    vergilyn.map[blog]=http://www.cnblogs.com/VergiLyn/
    vergilyn.map[name]=VergiLyn
    vergilyn.map[remark]=备注,中文23333
    
    ## list
    vergilyn.list[0]=Carpenters
    vergilyn.list[1]=Celine Dion
    vergilyn.list[2]=Bon Jovi
    vergilyn.list[3]=Taylor Swift
    
    ## array
    vergilyn.array[0]=I Don't Wanna Live Forever
    vergilyn.array[1]=Safe And Sound
    vergilyn.array[2]=22
    vergilyn.array[4]=Unpredictable Story
    vergilyn.array[8]=No One
    
    vergilyn.str=string
    vergilyn.num=124
    vergilyn.date=2017-01-14 23:55:19
    vergilyn.isSuccess=false
    package com.vergilyn.demo.springboot.properties.bean;
    
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    @Configuration
    @ConfigurationProperties(prefix = "vergilyn")
    @PropertySource("classpath:config/properties/ComplexProperty.properties")
    @Component
    public class ComplexPropertyBean {
        private Map<String, Object> map;
        private List<String> list;
        private String[] array;
    
        //省略 set/get
    }
    

    三、随机数

      如果要知道详细的,可以自行baidu、google。

    ## RandomPropertyBean.properties
    ## 随机值注入
    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]}
    package com.vergilyn.demo.springboot.properties.bean;
    
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    
    @Configuration
    @ConfigurationProperties()
    @PropertySource("classpath:config/properties/RandomProperty.properties")
    @Component
    public class RandomPropertyBean {
    
        @Value("${my.secret}")
        private String secret;
        @Value("${my.number}")
        private int number;
        @Value("${my.bignumber}")
        private long bignumber;
        @Value("${my.number.less.than.ten}")
        private int intten;
        @Value("${my.number.in.range}")
        private int range;
    
        // 省略 set/get
    }
    

    (注意可能需要在application.properties中配置@Value常量。详见github源码。)

    package com.vergilyn.demo.springboot.properties;
    
    import com.vergilyn.demo.springboot.properties.bean.BasePropertyBean;
    import com.vergilyn.demo.springboot.properties.bean.ComplexPropertyBean;
    import com.vergilyn.demo.springboot.properties.bean.RandomPropertyBean;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    
    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    @PropertySource(value={"classpath:config/application.properties"}
            , ignoreResourceNotFound = true)
    @Controller
    public class PropertyApplication {
    
        @Autowired
        BasePropertyBean base;
        @Autowired
        ComplexPropertyBean complex;
        @Autowired
        RandomPropertyBean random;
    //    @Autowired
    //    RelaxedBindPropertyBean relaxed;
    
        @Value("${CONSTANT_PASSWORD}")
        private String password;
    
    
        public static void main(String[] args) {
            SpringApplication.run(PropertyApplication.class, args);
        }
    
        @RequestMapping("/property")
        public String property(@RequestParam(value="name", required=false, defaultValue="${CONSTANT_USER}") String name
                , Model model) {
            model.addAttribute("name", name);
            model.addAttribute("password", password);
            System.out.println(base);
            System.out.println(complex);
            System.out.println(random);
    //        System.out.println(relaxed);
            return "custom";
        }
    }
    
    
    PropertyApplication.java

    github :

      https://github.com/vergilyn/SpringBootDemo

      自己学习spring boot的项目,并不是像官方samples一样是一个功能是一个项目,我是把所有都放在一个项目。

      所以注意看application-{profile}.properties和application.properties的配置。

      因为是一个项目,所以pom引入了很多jar。所以,可能有些properties配置是必须的。

     

  • 相关阅读:
    Java 进程占用内存过多,幕后元凶原来是线程太多
    领域驱动设计系列文章(3)——有选择性的使用领域驱动设计
    领域驱动设计系列文章(1)——通过现实例子显示领域驱动设计的威力
    RabbitMQ
    Redis与Memcached的区别
    memcached源码分析-----slab内存分配器
    C# Finalize和Dispose的区别
    [IoC容器Unity]第四回:使用范例
    [IoC容器Unity]第三回:依赖注入
    [IoC容器Unity]第二回:Lifetime Managers生命周期
  • 原文地址:https://www.cnblogs.com/VergiLyn/p/6533804.html
Copyright © 2020-2023  润新知