Spring5应用之自定义类型转换器

作者简介 :☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏
当前专栏Spring5应用专栏_Aomsir的博客

前言

在在我们之前的文章中,我们均采用spring配置文件进行开发。不知道大家是否注意到,配置文件里的依赖注入,除了引用类型外,基本都是字符串类型 。但在bean对应的类中,却往往使用如Integer 这样的类型。这背后是如何实现的呢?

类型转换器

Spring想到了这一点,提供了类型转换器 ,通过类型转换器把配置文件中字符串类型的数据,转换成了对象中成员变量对应类型的数据,进而完成了注入。如上图

自定义类型转换器

spring为我们提供了很多的类型转换器,比如简单类型转换器数组转换器集合类型转换器 等等,但还是会有场景需要我们自己进行类型转换,如下String转Date类型

错误分析

我为IoC容器准备了一个实体类、一份配置文件和一个测试方法,代码如下所示。在进行测试时,我遇到了一个异常,提示无法将String类型转换为Date类型 。这表明Spring无法自动执行String到Date的类型转换。为什么Spring不能自动转换呢?实际上,Spring提供了默认的类型转换器,但是只支持格式为yyyy/MM/dd的日期转换,而我们在测试中使用的是yyyy-MM-dd格式,因此需要我们程序员来自定义类型转换器

java 复制代码
public class Person implements Serializable {
    private String name;
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
xml 复制代码
<bean id="person" class="com.aomsir.basic.converter.Person">
    <property name="name" value="Aomsir" />
    <property name="birthday" value="2023-09-13" />
</bean>
java 复制代码
public class TestSpring {
    @Test
    public void test12() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        com.aomsir.basic.converter.Person person = ctx.getBean("person", com.aomsir.basic.converter.Person.class);

        System.out.println("person = " + person);
        System.out.println("birthday = " + person.getBirthday());
    }
}

自定义开发

  • 开发步骤

    • 创建转换器类,实现Converter接口
    • 编写spring配置文件进行注册
  • 接口说明

    • 接口中第一个泛型是原类型,第二个泛型是目标类型
    • 接口方法的参数是原数据,返回值是转换好后的对应数据
  • 注意:类型注册器id值必须是conversionService

java 复制代码
public class MyDateConverter implements Converter<String, Date> {

    /**
     * 将字符串类型转换为日期类型
     * @param s
     * @return
     */
    @Override
    public Date convert(String s) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Date date = null;
        try {
            date = sdf.parse(s);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return date;
    }
}
xml 复制代码
<bean id="person" class="com.aomsir.basic.converter.Person">
    <property name="name" value="Aomsir" />
    <property name="birthday" value="2023-09-13" />
</bean>

<!--将MyDateConverter创建出来-->
<bean id="myDateConverter" class="com.aomsir.basic.converter.MyDateConverter" />

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <ref bean="myDateConverter" />
        </set>
    </property>
</bean>

参考文献

相关推荐
卷无止境3 分钟前
手写 SQL 在 Tortoise ORM 里到底能派上什么用场
后端·python·fastapi
再吃一根胡萝卜6 分钟前
从 Docker 到 Kubernetes:微服务的“操作系统”长什么样?
后端
卷无止境6 分钟前
FastAPI、Tortoise ORM 与 PostgreSQL 三件套 是否好用呢?
后端·python·fastapi
程序员爱钓鱼13 分钟前
Rust Trait详解:定义共享行为与抽象接口
后端·面试·rust
都叫我大帅哥13 分钟前
@EnableTransactionManagement 详解:Spring 声明式事务的基石
java·spring
再吃一根胡萝卜15 分钟前
分布式事务:从“强一致”到“最终一致”,我为什么在微服务里放弃了 2PC?
后端
再吃一根胡萝卜17 分钟前
从 Django 到 Spring Cloud:一个全栈开发者的微服务思考
后端
程序员爱钓鱼18 分钟前
Go 编程实战:切片 Slice——灵活的动态数据集合
后端·面试·go
再吃一根胡萝卜7 小时前
微服务治理的“四大护法”:从 Django 视角理解 Spring Cloud 核心组件
后端
再吃一根胡萝卜7 小时前
面试终极挑战:如何用 Django 经验,回答 Java 微服务实战问题?
后端