【Spring @Value 扩展 文件 File 对象 Object 数据转换】


前言

有时项目中需要使用各种文件:sql文件、lua脚本文件、json文件、js文件…。

需要对这些文件的内容进行注入到应用,转换为对象封装到Bean属性中进行处理。
这里使用@Value进行扩展,支持从类路径上的文件转为我们想要的Java 对象。


一、@Value注入原理

@Value由AutowiredAnnotationBeanPostProcessor进行处理。

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor继承了MergedBeanDefinitionPostProcessor,可以合并BeanDefinition,在合并BeanDefinition过程中的钩子方法中,查找bean的所有依赖,包装为InjectionMetadata。
在这里插入图片描述
在这里插入图片描述
在postProcessProperties()方法中,通过InjectionMetadata注入,分为AutowiredFieldElement、AutowiredMethodElement,注入的底层是借助BeanFactory去查找依赖的bean或属性。
在这里插入图片描述
最终调用到DefaultListableBeanFactory#resolveDependency()。
这里会使用到TypeConverter来对@Value的依赖项进行属性注入,所以我们可以在这里扩展。
"classpath: xxx文件" -> Java Object

有三种方式扩展

  • 自定义PropertyEditor
  • 自定义Converter
  • 自定义Formmater

二、扩展PropertyEditor

自定义PropertyEditor

public class FileToJsonObjectEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            this.setValue(JSONObject.parseObject(StreamUtils.copyToString(new DefaultResourceLoader().getResource(text).getInputStream(), Charset.defaultCharset())));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

注册自定义PropertyEditor

@Bean
public CustomEditorConfigurer customEditorConfigurer() {
    CustomEditorConfigurer configurer = new CustomEditorConfigurer();
    configurer.setCustomEditors(Collections.singletonMap(JSONObject.class, FileToJsonObjectEditor.class));
    return configurer;
}

三、扩展Converter

自定义Converter

public class FileToJsonObjectConverter implements Converter<String, JSONObject> {
    @Override
    public JSONObject convert(String source) {
        try {
            return JSONObject.parseObject(StreamUtils.copyToString(new DefaultResourceLoader().getResource(source).getInputStream(), Charset.defaultCharset()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

注册自定义Converter

@Bean("conversionService")
public ConversionServiceFactoryBean fonversionServiceFactoryBean() {
    ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
    factoryBean.setConverters(Collections.singleton(new FileToJsonObjectConverter()));
    return factoryBean;
}

四、扩展Formmater

自定义Formmater

public class FileToJsonObjectFormatter implements Formatter<JSONObject> {
    @Override
    public JSONObject parse(String text, Locale locale) {
        try {
            return JSONObject.parseObject(StreamUtils.copyToString(new DefaultResourceLoader().getResource(text).getInputStream(), Charset.defaultCharset()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String print(JSONObject object, Locale locale) {
        return object.toJSONString();
    }
}

注册自定义Formmater

@Bean("conversionService")
public FormattingConversionServiceFactoryBean formattingConversionServiceFactoryBean() {
    FormattingConversionServiceFactoryBean factoryBean = new FormattingConversionServiceFactoryBean();
    factoryBean.setFormatters(Collections.singleton(new FileToJsonObjectFormatter()));
    return factoryBean;
}

五、效果

在这里插入图片描述

在这里插入图片描述


总结

以.json文件为例,介绍了从classpath: xxx文件 -> Java Object的Bean属性注入数据转换。

Sping支持3种转换方式,PropertyEditor,Converter,Formmater:

  • PropertyEditor 是java bean规范的一部分。只能用于字符串和Java对象的转换,不适用于任意两个Java类型之间的转换;在类型转换时不能利用上下文信息(如注解、宿主类结构)实施高级转换逻辑。
  • Converter 是一种简单通用的类型转换机制,可以将一种类型转换成另一种类型。从某种程度上,Converter包含Editor。如果出现需要从string转换到其他类型。首选Editor。
  • Formmater 则是主要是针对 Client / Server 之间的对象互相转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值