1 缘起

我都有些意外,为什么会写出来这样的文章。
最近学习、研究SpringBoot相关组件源码时,
如rabbitmq、resilience4j和gateway,
才发现@ConfigurationProperties可以映射实例化的对象、列表、HashMap,
吐槽一下:为什么我在学习使用@ConfigurationProperties时没有想到这些应用?(cai)
这篇文章耗时一个月,
因为一个组件对应一个类型,
用了一个月学习这三个组件,所以,总结出来的时间跨度是1个月,
于是,本文新鲜出炉,作为笔记。

2 映射实例化的对象

从Rabbimq中学到。

yml映射的数据为实例化的对象,即在@ConfigurationProperties标注的类中,

属性为实例化的对象,

这样的作用是什么?应用场景呢?

就是多一层嵌套,方便集成属性。

源码位置:org.springframework.boot.autoconfigure.amqp.RabbitProperties

源码如下图所示。

ConfigurationProperties加载list对象的配置_rabbitmq

2.1 基础实体

package com.monkey.springboottemplate.common.entity;

/**
 * 梦想实体.
 *
 * @author xindaqi
 * @date 2022-04-20 9:52
 */
public class DreamEntity {

    /**
     * 你的梦想是什么
     */
    private String whatDream;

    /**
     * 为什么有这个/类/种梦想
     */
    private String whyDream;

    public void setWhatDream(String whatDream) {
        this.whatDream = whatDream;
    }

    public String getWhatDream() {
        return whatDream;
    }

    public void setWhyDream(String whyDream) {
        this.whyDream = whyDream;
    }

    public String getWhyDream() {
        return whyDream;
    }

    @Override
    public String toString() {
        return "DreamEntity{" +
                "whatDream='" + whatDream + '\'' +
                ", whyDream='" + whyDream + '\'' +
                '}';
    }
}

2.2 映射类

package com.monkey.springboottemplate.common.config;

import com.monkey.springboottemplate.common.entity.DreamEntity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * My属性配置.
 *
 * @author xindaqi
 * @date 2022-04-20 9:59
 */
@Component
@ConfigurationProperties(prefix = "my")
public class MyProperties {

    private String name;

    private final DreamEntity dreamEntity = new DreamEntity();

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public DreamEntity getDreamEntity() {
        return dreamEntity;
    }

    @Override
    public String toString() {
        return "MyProperties{" +
                "name='" + name + '\'' +
                ", dreamEntity=" + dreamEntity +
                '}';
    }
}

2.3 配置

my:
  name: xiaoqi
  dream-entity:
    what-dream: To Be a CEO
    why-dream: Achieve my other dream

2.4 测试

package com.monkey.springboottemplate;

import com.monkey.springboottemplate.common.config.HashMapProperties;
import com.monkey.springboottemplate.common.config.MyProperties;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;
import java.util.Optional;
import java.util.stream.Stream;

@SpringBootTest
class SpringBootTemplateApplicationTests {

	private static final Logger logger = LoggerFactory.getLogger(SpringBootTemplateApplicationTests.class);

	@Autowired
	MyProperties myProperties;

	@Test
	public void myPropertiesTest() {
		logger.info(">>>>>>>>>My properties:{}", myProperties);
	}
}

ConfigurationProperties加载list对象的配置_分布式_02

3 映射HashMap

从reslilience4j中学习。

映射的类中属性为HashMap。

为什么?

因为,HashMap自身集合属性可以存储多key,value,

满足多种配置的需求。

使用形式要注意,使用属性名作为第一级,key作为第二级,值为第三级。

源码位置:io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties

源码如下图所示。

ConfigurationProperties加载list对象的配置_分布式_03

3.1 映射类

package com.monkey.springboottemplate.common.config;

import com.monkey.springboottemplate.common.entity.DreamEntity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * HashMap映射.
 *
 * @author xindaqi
 * @date 2022-05-06 16:18
 */
@Component
@ConfigurationProperties(prefix = "hashmap")
public class HashMapProperties {

    private Map<String, DreamEntity> happyPerson = new HashMap<>();

    private Map<String, DreamEntity> richPerson = new HashMap<>();

    public void setHappyPerson(Map<String, DreamEntity> happyPerson) {
        this.happyPerson = happyPerson;
    }

    public void setRichPerson(Map<String, DreamEntity> richPerson) {
        this.richPerson = richPerson;
    }

    public DreamEntity getHappyPerson(String key1) {
        return happyPerson.get(key1);
    }

    public DreamEntity getRichPerson(String key2) {
        return richPerson.get(key2);
    }

    @Override
    public String toString() {
        return "HashMapProperties{" +
                "happyPerson=" + happyPerson +
                ", richPerson=" + richPerson +
                '}';
    }
}

3.2 配置

hashmap:
  happyPerson:
    key1:
      what-dream: To Be a Happy person
      why-dream: Enjoy myself
  richPerson:
    key2:
      what-dream: To Be a Rich person
      why-dream: Buy things where I can

3.3 测试

package com.monkey.springboottemplate;

import com.monkey.springboottemplate.common.config.HashMapProperties;
import com.monkey.springboottemplate.common.config.MyProperties;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;
import java.util.Optional;
import java.util.stream.Stream;

@SpringBootTest
class SpringBootTemplateApplicationTests {

	private static final Logger logger = LoggerFactory.getLogger(SpringBootTemplateApplicationTests.class);

	@Autowired
	HashMapProperties hashMapProperties;

	@Test
	public void hashMapPropertiesTest() {
		logger.info(">>>>>>>>>HashMap properties:{}", hashMapProperties);
	}

}

ConfigurationProperties加载list对象的配置_List_04

4 映射列表

从Gateway源码中学习。

映射类的属性为List,

为什么使用List?

这个是映射实例化对象的扩展,如果有多个配置,

则需要使用集合的方式,配置。

配置方式需要注意,属性名称为第一级,集合中的数据使用横线-分隔多个对象,

即一个横线,一个对象。

源码位置:org.springframework.cloud.gateway.config.GatewayProperties

源码如下图所示。

ConfigurationProperties加载list对象的配置_java_05

4.1 映射类

package com.monkey.springboottemplate.common.config;

import com.monkey.springboottemplate.common.entity.UserEntity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * List类型数据.
 *
 * @author xindaqi
 * @date 2022-05-26 10:32
 */
@Component
@ConfigurationProperties(prefix = "list")
public class ListProperties {
    private List<UserEntity> users;

    public void setUsers(List<UserEntity> users) {
        this.users = users;
    }

    public List<UserEntity> getUsers() {
        return users;
    }

    @Override
    public String toString() {
        return "ListProperties{" +
                "users=" + users +
                '}';
    }
}

4.2 配置

list:
  users:
    - uid: 0x0001
      nickname: xiaohua
    - uid: 0x002
      nickname: xiaolan

4.3 测试

package com.monkey.springboottemplate;

import com.monkey.springboottemplate.common.config.HashMapProperties;
import com.monkey.springboottemplate.common.config.ListProperties;
import com.monkey.springboottemplate.common.config.MyProperties;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;
import java.util.Optional;
import java.util.stream.Stream;

@SpringBootTest
class SpringBootTemplateApplicationTests {

	private static final Logger logger = LoggerFactory.getLogger(SpringBootTemplateApplicationTests.class);
	
	@Autowired
	ListProperties listProperties;

	@Test
	public void listPropertiesTest() {
		logger.info(">>>>>>>>List properties:{}", listProperties);
	}
}

ConfigurationProperties加载list对象的配置_rabbitmq_06

5 小结

(1)映射实例化的对象:多一层嵌套,方便集成属性;
(2)映射HashMap:HashMap自身集合属性可以存储多key,value,满足多属性配置;
(3)映射List:映射实例化对象的扩展,映射对象集合。