【Springboot】注解读取配置文件自定义配置信息

springboot项目的配置文件信息一般放在application.yml(也有命名application.properties)文件中,当项目启动的时候,我们可以只修改配置文件中的配置,而不修改代码。如果不在配置文件中配置信息,虽然也可以实现功能,但是容易出现问题。

例如:跨系统交互时,另外一个系统(系统A)的域名或者端口发生变化,我们需要在自己的项目中对其地址信息进行修改。如果不在配置文件中进行配置,我们需要在代码中修改所有与A系统交互时的访问地址信息修改,如果存在多处与系统A交互,需要修改多处地方。修改相对较大,而且修改完之后,还需要重新发版。万一在修改时,不小心碰到了其他代码,修改了其他代码逻辑,这上线发版后出问题就麻烦了,就等着背一个线上case事故吧。

如果我们配置在配置中配置改变量,所有用到该变量的地方,我们从配置文件中进行读取。即使系统A的域名发生变化,我们可以只修改配置文件中改变量的值,不会影响到其他代码。当然,这时也有人问,你最终还是修改了东西,难免不会粗心大意碰到其他代码,这不是照样存在风险吗?

对于这个问题,可能是问问题的人还没进入公司工作,也可能是我了解的太low了。为什么这么说呢,因为这些配置文件中的值,是不由程序员进行维护的,一般这些配置文件在公司都是有专门的运维进行维护的,在上线的时候,你提供配置文件的线上配置,运维会对其进行配置或者对你配置的进行覆盖,因此,由运维进行操作,运维只会修改配置文件中的值,不会修改代码。(当然这是我所在公司的风格,其他公司我不了解)





OK,废话讲这么多了,开始正题。

1、基本配置变量读取

首先我们先介绍一下最基本的配置,没有数组list对象,没有map对象。

注意:每个键也就是(冒号左面的值),键之后必须要有一个空格,在idea下,键会变成黄色(也就是冒号后面要有一个空格)

配置文件中的配置:

info:
  name: mwl
  love: lwm
  type: alone

对于这种只包含变量的我们一般采取两种方式取值,推荐第二种方式。

第一种方法,(变量值少时推荐使用种方法,不然需要定义多个变量进行接收):

		@Value("${info.name}")
    private String NAME;
    @Test
    public void TestValue(){
        System.out.println(NAME);
    }

第二种方法,采用**@ConfigurationProperties注解,其中prefix对应配置文件前缀,@Component注解用于添加到容器中,@Data**注解属于插件lombok中的注解,用于减少get、set以及toString等方法的代码量。

package com.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author: MWL
 * @date: 2020/3/6 9:59 上午
 **/
@Component
@Data
@ConfigurationProperties(prefix = "info")
public class InfoConfig {
    private String name;
    private String love;
    private String type;
}

单元自测类方法测试:

    @Value("${info.name}")
    private String NAME;
    @Resource
    private InfoConfig infoConfig;

    @Test
    public void TestConfigValue(){
        System.out.println("infoConfig.toString():"+infoConfig.toString());
        System.out.println("infoConfig.getName():"+infoConfig.getName());
        System.out.println("NAME:"+NAME);

    }
//程序运行结果如下:
infoConfig.toString()InfoConfig(name=mwl, love=lwm, type=alone)
infoConfig.getName():mwl
NAME:mwl

2、配置变量中嵌套对象

在原有的配置文件中添加(first和second)信息,如:

info:
  name: mwl
  love: lwm
  type: alone
  first:
    hx: zui
    face: yan
    way:  back
  second:
    wyy: nose
    test: mouse

代码如下:

package com.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author: MWL
 * @date: 2020/3/6 9:59 上午
 **/
@Component
@Data
@ConfigurationProperties(prefix = "info")
public class InfoConfig {
    private String name;
    private String love;
    private String type;
    private First first;
    private Second second;

    @Data
    static class First{
        private String hx;
        private String face;
        private String way;
    }

    @Data
    static class Second{
        private String wyy;
        private String test;
    }
}

运行代码:

    @Value("${info.name}")
    private String NAME;
    @Value("${info.first.hx}")
    private String HX;
    @Resource
    private InfoConfig infoConfig;

    @Test
    public void TestConfigValue(){
        System.out.println("infoConfig.toString():"+infoConfig.toString());
        System.out.println("infoConfig.getName():"+infoConfig.getName());
        System.out.println("infoConfig.getFirst():"+infoConfig.getFirst());
        System.out.println("HX:"+HX);

    }

//程序运行结果:
infoConfig.toString()InfoConfig(name=mwl, love=lwm, type=alone, first=InfoConfig.First(hx=zui, face=yan, way=back), second=InfoConfig.Second(wyy=nose, test=mouse))
infoConfig.getName():mwl
infoConfig.getFirst():InfoConfig.First(hx=zui, face=yan, way=back)
HX:zui

在上述代码中,存在两个问题

  • First和Second必须被static修饰,不然getFirst输出为null。
  • 如果我们想要获取First对象中的属性,我们发现infoConfig.getFirst()中没有其相关属性的get方法

如果我们想要获取First对象中的属性我们可以将First和Second对象定义在一个新的类中。如下:

package com.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author: MWL
 * @date: 2020/3/6 9:59 上午
 **/
@Component
@Data
@ConfigurationProperties(prefix = "info")
public class InfoConfig {
    private String name;
    private String love;
    private String type;
    private First first;
    private Second second;
}

============================================

package com.config;
import lombok.Data;

/**
 * @author: MWL
 * @date: 2020/3/6 10:56 上午
 **/
@Data
public class Second {
    private String wyy;
    private String test;
}

============================================
package com.config;

import lombok.Data;

/**
 * @author: MWL
 * @date: 2020/3/6 10:56 上午
 **/
@Data
public class First {
    private String hx;
    private String face;
    private String way;
}

//此时我们在运行上述测试类,发现可以获取到First中的属性

如果不使用对象嵌套对象的方法,可以在重新定义一套配置prefix = “info.first”,,如果将所有的代码放在一个类里,代码需要稍作改动,如下所示。

代码如下(为了便于区分,新建一个类用于测试):

package com.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author: MWL
 * @date: 2020/3/6 11:48 上午
 **/
@Configuration
public class InfoConfigProperties {
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "info")
    public static class InfoConfig{
        private String name;
        private String love;
        private String type;
    }

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "info.first")
    public static class FirstPlay {
        private String hx;
        private String face;
        private String way;
    }

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "info.second")
    public static class SecondPlay {
        private String wyy;
        private String test;
    }
}


    @Resource
    private InfoConfigProperties.FirstPlay firCon;
    @Test
    public void TestinfoPro(){
        System.out.println(firCon.getHx());

    }

3、list、map对象读取

配置文件如下(其中list、map的两种写法均可以读取到对应值,看个人习惯):

person:
  name: xiaoming
  full-name: 小明
  age: 23
  boss: false
  birth: 1995/10/04
  #list: a,b,c,d

#  list:
#    - a
#    - b
#    - c
#    - d

  list: [a,b,c,100]

#  map: {key1: value1,key2: value2}
  map:
    key1: 15
    key2: 2
  dog:
    name: tom
    age: 3

java代码:

package com.config.entity;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author: MWL
 * @date: 2020/3/6 10:53 上午
 **/
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private String fullName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private List<String> list;
    private Map<String, String> map;
    private Dog dog;
}

=====================================
  //测试类代码:
    @Autowired
    private Person person;
    @Test
    public void TestPerson(){
        System.out.println(person.toString());
        System.out.println(person.getDog().getAge());
        System.out.println(person.getBoss());
        System.out.println(person.getBirth());
        System.out.println(person.getList().get(3));
        System.out.println(person.getMap().get("key1"));

    }

//运行结果:
Person(name=xiaoming, fullName=小明, age=23, boss=false, birth=Wed Oct 04 00:00:00 CST 1995, list=[a, b, c, d], map={key1=value1, key2=value2}, dog=Dog(name=tom, age=3))
3
false
Wed Oct 04 00:00:00 CST 1995
d
value1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章