package cn.java.demo.base.internal.properties_config;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.bind.PropertiesConfigurationFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.*;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @date 2020-12-03 13:54
*/
@Slf4j
public class PropertiesConfigurationFactoryTest {
/**
* @see org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor #postProcessBeforeInitialization()
*/
public static void main(String[] args) {
FooOneConfig fooOneConfig = new FooOneConfig();
PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<Object>(fooOneConfig);
// 数据源
factory.setPropertySources(getPropertySources());
// 校验器
factory.setValidator(null);
// 类型转换器
factory.setConversionService(getDefaultConversionService());
// 配置属性
ConfigurationProperties annotation = getConfigurationProperties();
if (!ObjectUtils.isEmpty(annotation)) {
log.info("注解信息 annotation = {}", annotation);
factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());
factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());
factory.setExceptionIfInvalid(annotation.exceptionIfInvalid());
factory.setIgnoreNestedProperties(annotation.ignoreNestedProperties());
if (StringUtils.hasLength(annotation.prefix())) {
factory.setTargetName(annotation.prefix());
}
}
// 绑定数据
try {
factory.bindPropertiesToTarget();
} catch (Exception ex) {
ex.printStackTrace();
}
log.info("绑定结果 fooOneConfig = {}", fooOneConfig);
}
/**
* 数据源
*/
static PropertySources getPropertySources() {
MutablePropertySources mutablePropertySources = new MutablePropertySources();
{
// 构造 MapPropertySource
Map mapData = new HashMap<>();
mapData.put("id", 1);
mapData.put("name", 100);
MapPropertySource mapPropertySource = new MapPropertySource("fooOneMapPropertySource", mapData);
// 添加
mutablePropertySources.addLast(mapPropertySource);
}
PropertySources propertySources = new FlatPropertySources(mutablePropertySources);
return propertySources;
}
@ConfigurationProperties
static public void method0() {
}
static ConfigurationProperties getConfigurationProperties() {
try {
return PropertiesConfigurationFactoryTest.class.getMethod("method0").getAnnotation(ConfigurationProperties.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
/**
* 类型转换器
*/
private static ConversionService getDefaultConversionService() {
DefaultConversionService conversionService = new DefaultConversionService();
return conversionService;
}
@Data
private static class FooOneConfig {
private Integer id;
private String name;
}
private static class FlatPropertySources implements PropertySources {
private PropertySources propertySources;
FlatPropertySources(PropertySources propertySources) {
this.propertySources = propertySources;
}
@Override
public Iterator<PropertySource<?>> iterator() {
MutablePropertySources result = getFlattened();
return result.iterator();
}
@Override
public boolean contains(String name) {
return get(name) != null;
}
@Override
public PropertySource<?> get(String name) {
return getFlattened().get(name);
}
private MutablePropertySources getFlattened() {
MutablePropertySources result = new MutablePropertySources();
for (PropertySource<?> propertySource : this.propertySources) {
flattenPropertySources(propertySource, result);
}
return result;
}
private void flattenPropertySources(PropertySource<?> propertySource,
MutablePropertySources result) {
Object source = propertySource.getSource();
if (source instanceof ConfigurableEnvironment) {
ConfigurableEnvironment environment = (ConfigurableEnvironment) source;
for (PropertySource<?> childSource : environment.getPropertySources()) {
flattenPropertySources(childSource, result);
}
} else {
result.addLast(propertySource);
}
}
}
}