一、@ConfigurationProperties注解作用方法
#数据源
spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.druid.write.username=root
spring.datasource.druid.write.password=1
spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.druid.read.username=root
spring.datasource.druid.read.password=1
spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver
java代码:
@Configuration
public class DruidDataSourceConfig {
/**
* DataSource 配置
* @return
*/
@ConfigurationProperties(prefix = "spring.datasource.druid.read")
@Bean(name = "readDruidDataSource")
public DataSource readDruidDataSource() {
return new DruidDataSource();
}
/**
* DataSource 配置
* @return
*/
@ConfigurationProperties(prefix = "spring.datasource.druid.write")
@Bean(name = "writeDruidDataSource")
@Primary
public DataSource writeDruidDataSource() {
return new DruidDataSource();
}
}
也许有的人看到这里会比较疑惑,prefix并没有指定配置的全限定名,那它是怎么进行配置绑定的呢?
相信大家肯定了解@Value注解,它可以通过全限定名进行配置的绑定,这里的ConfigurationProperties其实就类似于使用多个@Value同时绑定,绑定的对象就是DataSource类型的对象,而且是 隐式绑定 的,意味着在配置文件编写的时候需要与对应类的字段名称 相同.比如上述spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa
当然了,你也可以随便写个配置,比如spring.datasource.druid.write.uuu=www.baidu.com
,此时你只需要在注解中加上以下参数即可
以上就完成了多个数据源的配置,为读写分离做了铺垫
二、@ConfigurationProperties注解作用类
配置文件:
spring.datasource.url=jdbc:mysql://127.0.0.1:8888/test?useUnicode=false&autoReconnect=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
java代码:
@ConfigurationProperties(prefix = "spring.datasource")
@Component
public class DatasourcePro {
private String url;
private String username;
private String password;
// 配置文件中是driver-class-name, 转驼峰命名便可以绑定成
private String driverClassName;
private String type;
}
用法
@Controller
@RequestMapping(value = "/config")
public class ConfigurationPropertiesController {
@Autowired
private DatasourcePro datasourcePro;
@RequestMapping("/test")
@ResponseBody
public Map<String, Object> test(){
Map<String, Object> map = new HashMap<>();
map.put("url", datasourcePro.getUrl());
map.put("userName", datasourcePro.getUsername());
map.put("password", datasourcePro.getPassword());
map.put("className", datasourcePro.getDriverClassName());
map.put("type", datasourcePro.getType());
return map;
}
}
- @ConfigurationProperties 和 @value 有着相同的功能,但是 @ConfigurationProperties的写法更为方便
- @ConfigurationProperties 的 POJO类的命名比较严格,因为它必须和prefix的后缀名要一致, 不然值会绑定不上, 特殊的后缀名是“driver-class-name”这种带横杠的情况,在POJO里面的命名规则是 下划线转驼峰 就可以绑定成功,所以就是 “driverClassName”
三、配置属性自定义转换
当我们通过@ConfigurationProperties注解实现配置 bean的时候,如果默认的配置属性转换无法满足我们的需求的时候,我们可以根据自己的需求通过以下扩展方式对配置属性进行转换。
PropertyEditorSupport实现
下面的例子是把属性中定义的字符串转换成Movie,并且把name的值大写
继承PropertyEditorSupport并且实现PropertyEditorRegistrar接口
public class CustomMovieEditor extends PropertyEditorSupport implements PropertyEditorRegistrar {
@Override
public String getAsText() {
Movie movie = (Movie) getValue();
return movie == null ? "" : movie.getName();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("继承[PropertyEditorSupport]类,转换数据=" + text);
String[] data = text.split("-");
Movie movie = new Movie(data[0].toUpperCase(), Integer.parseInt(data[1]));
setValue(movie);
}
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Movie.class, this);
}
}
注册自定义的PropertyEditor
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
// 有两种注册方式 这是第一种
customEditorConfigurer.setPropertyEditorRegistrars(
new PropertyEditorRegistrar[]{ new CustomMovieEditor() });
// 第二 种
Map<Class<?>,Class<? extends PropertyEditor>> maps = new HashMap<>();
maps.put(Movie.class,CustomMovieEditor.class);
return customEditorConfigurer;
}
其中Movie类: ```java @Setter @Getter @AllArgsConstructor public class Movie {
private String name;
private Integer seat;
}
需要进行自定义属性类型转换的类:
```java
@Data
@ConfigurationProperties(prefix = "huanghe")
@Component
public class TestMovieProperties {
String name;
Movie movie;
}
启动测试类:
@RestController
public class ProductController_Consumer {
@Autowired
private TestMovieProperties movieProperties;
@RequestMapping(value = "/consumer/product/get/{id}")
public String get(@PathVariable("id") Long id) {
System.out.println(movieProperties);
return "demo";
}
}
会发现Movie的属性已经注册进去了。这种自定义属性配置自定义转换,适用@ConfigurationProperties
注解实现配置 bean的时候,如果默认的配置属性转换无法满足我们的需求的时候,我们可以根据自己的需求通过以下扩展方式对配置属性进行转换。
Converter接口+@ConfigurationPropertiesBinding注解
使用案例:https://www.dazhuanlan.com/zhangxiaohai/topics/1506334
//注意
@Component
@ConfigurationPropertiesBinding
public class StringToPersonConverter implements Converter<String, Person> {
@Override
public Person convert(String from) {
log.info("使用[Converter]接口,转换数据={}", from);
String[] data = from.split(",");
return Person.builder().name(data[0]).age(Integer.parseInt(data[1])).build();
}
}
总结
- 以上两种实现方式结果,但是Converter接口相比PropertyEditor接口更加灵活一些,PropertyEditor接口仅限于String转换,Converter可以自定义别的,并且PropertyEditor接口通常用于Controller中的接收参数的转换。
- @ConfigurationPropertiesBinding是限定符注解@Qualifier的派生类而已,参考org.springframework.boot.context.properties.ConversionServiceDeducer,以下是源代码片段
```java
@Autowired(required = false)
@ConfigurationPropertiesBinding
public void setConverters(List
> converters) {
}this.converters = converters;
/**
- A list of custom converters (in addition to the defaults) to use when
- converting properties for binding.
- @param converters the converters to set
*/
@Autowired(required = false)
@ConfigurationPropertiesBinding
public void setGenericConverters(List
converters) { this.genericConverters = converters; } ```
- Formatter接口是不能对属性完成转换的,因为ConversionServiceDeducer初始化的时候只获取GenericConverter和Converter接口
- 官方文档上还介绍了可以使用实现org.springframework.core.convert.ConversionService并且Bean名称也必须叫conversionService,不过大部分情况不推荐自己通过这种方式去实现这个接口,因为自己实现的ConversionService会替代默认的。具体参考ConversionServiceDeducer源码:
四、基于XML配置的方式
http://www.what21.com/sys/view/java_spring-java_1456896197847.html
https://blog.csdn.net/u010675669/article/details/86488575