背景
想通过 BeanDefinitionRegistryPostProcessor
代码注册bean, bean注册基于 ConfigurationProperties
配置实现
实现
application.yaml
1 2 3 4 5 6 7 8 9
| idea360: name: cuishiying blog: http://idea360.cn
cluster: companyid: g1: 1,2,3,4-10 g2: 10-100 g3: 100-200
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.example.demo.config;
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; import org.springframework.boot.env.PropertiesPropertySourceLoader; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.context.annotation.Configuration;
@Data @Configuration @ConfigurationProperties(prefix = "idea360") public class BinderProperties {
private String name;
private String blog;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.example.demo.config;
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.boot.context.properties.bind.BindResult; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.EnvironmentAware; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component;
@Slf4j @Component public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { log.info("exec custom postProcessBeanDefinitionRegistry"); }
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override public void setEnvironment(Environment environment) { BindResult<BinderProperties> bindResult = Binder.get(environment).bind("idea360", BinderProperties.class); BinderProperties binderProperties = bindResult.get(); log.info("binderProperties: {}", binderProperties); } }
|
日志输出
1 2
| 2023-08-18 14:46:55.979 INFO 15148 --- [ main] ustomBeanDefinitionRegistryPostProcessor : binderProperties: BinderProperties(name=cuishiying, blog=http://idea360.cn) 2023-08-18 14:46:55.979 INFO 15148 --- [ main] ustomBeanDefinitionRegistryPostProcessor : exec custom postProcessBeanDefinitionRegistry
|
Yaml基础使用
依赖
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.33</version> <scope>compile</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.15.0</version> </dependency>
|
java绑定对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package cn.idea360.yaml.yaml;
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
@Data @ConfigurationProperties(prefix = "cluster.companyid") public class ClusterProperties {
private List<String> g1; private List<String> g2; private List<String> g3;
}
|
单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| package cn.idea360.yaml;
import cn.idea360.yaml.yaml.ClusterProperties; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.util.ResourceUtils; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml;
import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Properties;
@Slf4j
class YamlDemoApplicationTests {
@Test void yaml() throws IOException { String yamlFile = "application.yaml"; InputStream inputStream = YamlDemoApplicationTests.class.getClassLoader().getResourceAsStream(yamlFile); String yaml = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()); System.out.println("原始yaml文本:\n" + yaml);
byte[] contentBytes = yaml.getBytes(StandardCharsets.UTF_8); YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); yamlPropertiesFactoryBean.setResources(new Resource[]{new ByteArrayResource(contentBytes)}); Properties properties = yamlPropertiesFactoryBean.getObject(); System.out.println("YamlPropertiesFactoryBean:\n" + properties);
StandardEnvironment environment = new StandardEnvironment(); DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader(); Resource resource = defaultResourceLoader.getResource(yamlFile); List<PropertySource<?>> propertySourceList = new YamlPropertySourceLoader().load("yaml", resource); propertySourceList.forEach(propertySource -> environment.getPropertySources().addLast(propertySource)); ClusterProperties clusterProperties = Binder.get(environment).bindOrCreate("cluster.companyid", ClusterProperties.class); System.out.println("Binder属性:\n" + clusterProperties); }
@Test void readYaml() throws Exception { InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("application.yaml"); String absolutePath = ResourceUtils.getFile("classpath:application.yaml").getAbsolutePath(); Yaml yaml = new Yaml(); Object load = yaml.load(inputStream); ObjectMapper objectMapper = new ObjectMapper(); log.info("path: {}, content: {}", absolutePath, objectMapper.writeValueAsString(load)); }
@Test void writeYaml() throws Exception { DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); options.setPrettyFlow(true); Yaml yaml = new Yaml(options);
String json = "{\"idea360\":{\"name\":\"cuishiying\",\"blog\":\"http://idea360.cn\"}}"; ObjectMapper objectMapper = new ObjectMapper(); Object yamlContent = objectMapper.readValue(json, Object.class); String dump = yaml.dump(yamlContent); log.info("yaml:\n{}", dump); }
}
|
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 原始yaml文本: idea360: name: cuishiying blog: http://idea360.cn
cluster: companyid: g1: 1,2,3,4-10 g2: 10-100 g3: 100-200 YamlPropertiesFactoryBean: {cluster.companyid.g1=1,2,3,4-10, idea360.name=cuishiying, cluster.companyid.g2=10-100, cluster.companyid.g3=100-200, idea360.blog=http://idea360.cn} Binder属性: ClusterProperties(g1=[1, 2, 3, 4-10], g2=[10-100], g3=[100-200])
|
yaml和json互转
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.13.5</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| private static String convertYamlToJson(String yaml) { try { ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); Object obj = yamlReader.readValue(yaml, Object.class); ObjectMapper jsonWriter = new ObjectMapper(); return jsonWriter.writerWithDefaultPrettyPrinter().writeValueAsString(obj); } catch (Exception ex) { ex.printStackTrace(); } return null; }
private static String convertJsonToYaml(String json) { try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(json); return new YAMLMapper().writeValueAsString(jsonNode); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; }
|