微服务架构 | nacos - [标准化接入: 各种类型引用]

@

§1 基础类型

§1.1 properties 注入

接收

@Value("${sdbc.nacos.sb.e.str}")
private String str;
@Value("${sdbc.nacos.sb.e.num}")
private Integer num;
@Value("${sdbc.nacos.sb.e.bool}")
private boolean bool;

配置

sdbc.nacos.sb.e.str=string
sdbc.nacos.sb.e.num=1234
sdbc.nacos.sb.e.bool=true

§1.2 yml 注入

接收

@Value("${sdbc.nacos.sb.e.str}")
private String str;
@Value("${sdbc.nacos.sb.e.num}")
private Integer num;
@Value("${sdbc.nacos.sb.e.bool}")
private boolean bool;

配置

sdbc:
  nacos:
    sc:
      e:
        str: as
        num: 12
        bool: true

§1.3 @ConfigurationProperties 注入

接收

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.eb")
public class EveryTypeBeanNacosConfig {
    private String str;
    private Integer num;
    private boolean bool;
}

配置

sdbc:
  nacos:
    sc:
      eb:
        str: df
        num: 34
        bool: false

§2 集合类型(Collection)

§2.1 properties 注入

要点:
线性集合,数组、list、set,均可以直接注入,如 sdbc.nacos.sb.e.strarr=a,b,c

也可以选择 SpEl 语法,但是引用与配置都需要调整,即下方 strarrr
另外,SpEl 语法中,数组通过 {} 而不是 [] 声明

接收

@Value("${sdbc.nacos.sb.e.strarr}")
private String[] strarr;
@Value("${sdbc.nacos.sb.e.numarr}")
private Integer[] numarr;
@Value("${sdbc.nacos.sb.e.strarr}")
private List<String> strlist;
@Value("#{${sdbc.nacos.sb.e.strarrr}}")
private List<String> strlistr;
@Value("${sdbc.nacos.sb.e.numarr}")
private List<Integer> numlist;
@Value("${sdbc.nacos.sb.e.strarr}")
private Set<String> strset;
@Value("${sdbc.nacos.sb.e.numarr}")
private Set<Integer> numset;

配置

sdbc.nacos.sb.e.strarr=a,b,c
sdbc.nacos.sb.e.numarr=1,100,-1
sdbc.nacos.sb.e.strarrr={"a","b","c"}

§2.2 yml 注入

  • 线性集合,数组、list、set,均可以直接注入,但只能使用 yml 行内配置,多行配置经实验不支持 @Value
  • 用 @Value("${}") 注解接收 [a,b,c] 的写法,经实测并不支持,会报错

接收

@Value("${sdbc.nacos.sc.e.strarr}")
private String[] strarr;
@Value("${sdbc.nacos.sc.e.strarr}")
private List<String> strlistr;
@Value("${sdbc.nacos.sc.e.strarr}")
private Set<String> strset;

配置

sdbc:
  nacos:
    sc:
      e:
        strarr: a,b,c

§2.3 @ConfigurationProperties 注入

ConfigurationProperties 下相对于 properties 配置更加灵活:a,b,c / [a,b,c] 以及多行配置方式都可以

接收

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.eb")
public class EveryTypeBeanNacosConfig {
    private List<Integer> numarr;
    private List<Integer> numlis;
    private List<Integer> numset;
}

配置

sdbc:
  nacos:
    sc:
      eb:
        numarr: 1,2,3
        numlis: [4,5,6]
        numset:
          - 7
          - 8
          - 9

§3 集合类型(Map)

§3.1 properties 注入

只能通过 SpEl 语法声明
值必须被引号包围,如 '{"a":"b"}' / "{'a':'b'}" 都可以
若 Map 中嵌套了集合,需要注意通过 {} 而不是 [] 声明(SpEl 语法要求)

接收

@Value("#{${sdbc.nacos.sb.e.map}}")
private Map<String,String> map;
@Value("#{${sdbc.nacos.sb.e.collmap}}")
private Map<String,List<String>> collmap;

配置

sdbc.nacos.sb.e.map={"a":"b"}
sdbc.nacos.sb.e.collmap={"a":{"a","b"},"x":{"x","y"}}

§3.2 yml 注入

@Value 下,只能通过 SpEl 语法声明
值必须被引号包围,如 '{"a":"b"}' / "{'a':'b'}" 都可以
若 Map 中嵌套了集合,需要注意通过 {} 而不是 [] 声明(SpEl 语法要求)

接收

@Value("#{${sdbc.nacos.sb.e.map}}")
private Map<String,String> map;
@Value("#{${sdbc.nacos.sb.e.collmap}}")
private Map<String,List<String>> collmap;

配置

sdbc:
  nacos:
    sc:
      e:
        map: '{"a":"b"}'
        collmap: '{"a":{"a","b"},"x":{"x","y"}}'

§3.3 @ConfigurationProperties 注入

接收

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.eb")
public class EveryTypeBeanNacosConfig {
    private Map<String,String> map;
    private Map<String, List<String>> collmap;
}

配置

sdbc:
  nacos:
    sc:
      eb:
        map:
          x: y
        collmap:
          a:
            - aa
            - bb
          x:
            - xx
            - yy

§4 空集合类型

§4.1 properties 注入

注意 SpEl 语法中空集合是 {}/{:},不是 []/{}
使用场景:通常是业务中需要一个可能为空的容器,比如黑白名单,并且不想对它做判空处理

sdbc.nacos.sb.e.emtpyarr=
sdbc.nacos.sb.e.emtpyarrr={}
sdbc.nacos.sb.e.emtpymap={:}
@Value("${sdbc.nacos.sb.e.emtpyarr}")
private List<String> emptyarr;
@Value("#{${sdbc.nacos.sb.e.emtpyarrr}}")
private List<String> emptyarrr;
@Value("#{${sdbc.nacos.sb.e.emtpymap}}")
private Map<String,String> emptymap;

§4.2 yml 注入

注意

  • yml 中,空数组不能用无值声明,空 List 不能用 {} 声明,在 yml 下,上述二者均需要 [] 声明
  • 空 Map 的声明需要 SpEl 声明,值需要被引号包围(单引双引都行),即 '{:}' 。需要注意的是 '{}' 不会报错,但实际会注入为 null(空指针警告)

使用场景:通常是业务中需要一个可能为空的容器,比如黑白名单,并且不想对它做判空处理

接收

@Value("${sdbc.nacos.sc.e.emptyarr}")
private String[] emptyarr;
@Value("${sdbc.nacos.sc.e.emtpylis}")
private List<String> emptylis;
@Value("#{${sdbc.nacos.sc.e.emtpymap}}")
private Map<String,String> emptymap;

配置

sdbc:
  nacos:
    sc:
      e:
        emptyarr: []
        emtpylis: []
        emtpymap: '{:}'

§4.3 @ConfigurationProperties 注入

@ConfigurationProperties 不支持配置空集合,实测使用 空值、[]、{}、{:} 要不是 null 要不报错
只能在配置类中直接声明默认集合(数组不用)

接收

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.eb")
public class EveryTypeBeanNacosConfig {
    private String[] emptyarr;
    private List<String> emptylis = new ArrayList<>();
    private Map<String,String> emptymap = new HashMap<>();
}

配置

sdbc:
  nacos:
    sc:
      eb:
        emptyarr:
        emtpylis: 
        emtpymap: 

§5 自定义 Bean 类型

自定义 Bean 类型不支持 @Value 注入,都是 @ConfigurationProperties 注入

§5.1 properties 注入

properties 下本质上都是 String->对象 的类型转换,会因缺少转换器而报错
因此,需要补对应的转换器给 spring,
因为,转换器的泛型是声明在类(而不是方法)上的,如 Converter<Source,Target>
所以,把转换器声明给 spring 时(就是给了个实例)已经实例化,因此目标类型就已经确定了
故,每个目标类型都需要转换器
结论:可以实现但是有病

接收

//一般类
public class A {
    private String x;
    private String y;
}

//泛型类
public class B<T> {
    private String code;
    private T data;
}

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.o")
public class ObjectDiNacosConfig {
    private A a;
    private List<A> alist;
    private B<String> b;
    private Map<String, B<A>> bsmap;
}

配置

# 对象类型
sdbc.nacos.sb.o.a={"x":"1a"}
sdbc.nacos.sb.o.aList=[{"x":"1a"}]
# 泛型类型
sdbc.nacos.sb.o.b={"code":"2b","data":"ddd"}
sdbc.nacos.sb.o.bsMap={"first":{"code":"2b","data":{"x":"1a"}},"second":{"code":"2c","data":{"x":"xy"}}}

Converter

@Configuration
public class GsonConfigurationPropertiesConverter {
    private static final Gson gson = new GsonBuilder().serializeNulls().create();
    //通用写法,只需要替换目标类型部分为实际返回类型即可(下面的Map<String, B<A>>)
    //这里省略了
    //Converter<String, A>
    //Converter<String, List<A>>
    //Converter<String, B<A>>
    @Bean
    @ConfigurationPropertiesBinding
    public Converter<String, Map<String, B<A>>> string2BsmapConvert() {
        return new Converter<String, Map<String, B<A>>>() {
            @Override
            public Map<String, B<A>> convert(String x) {
                return doConvert(x, new TypeToken<Map<String, B<A>>>() {}.getType());
            }
        };
    }
    public<T> T doConvert(String s, Type t){  return gson.fromJson( s, t); }
}

§5.2 yml 注入

yml 下,注入对象、对象集合、带泛型对象、带泛型对象集合都有良好的支持
与 properties 不同,不需要自定义 Converter
推荐

接收

//一般类
public class A {
    private String x;
    private String y;
}

//泛型类
public class B<T> {
    private String code;
    private T data;
}

@Component
@ConfigurationProperties(prefix = "sdbc.nacos.sc.o")
public class ObjectDiNacosConfig {
    private A a;
    private List<A> alist;
    private B<String> b;
    private Map<String, B<A>> bsmap;
}

配置

sdbc:
  nacos:
    sc:
      o:
        a:
          x: 1
          y: zz
        alist:
          - x: 2
            y: a
          - x: 666
            y: 999
        b:
          code: a
          data: xx
        bsmap:
          b:
            code: 200
            data: 
              x: 一轮明月照九州
              y: 侯杰
posted @ 2025-05-21 11:09  问仙长何方蓬莱  阅读(56)  评论(0)    收藏  举报