为什么使用自定义属性编辑器
举个栗子:
Bean
@Data
public class Person {
private String name;
private String gender;
private Integer age;
private Date birthDay;
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.ligudo.demo.model.Person">
<property name="birthDay" value="2021-01-01"></property>
</bean>
</beans>
通过 applicationContext.xml 注册 Person,Person::birthDay 为 Date 类型。通过以下方式获取 Person 对象会报错,即无法将 string 类型属性值直接转换为 Date 类型。这就需要告诉 spring 框架,在填充 Bean 对象属性时,如何自定义的处理其中的某些属性。
public class SpringTest {
@Test
public void test(){
ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = application.getBean(Person.class);
System.out.println(person);
}
}
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Date' for property 'birthDay': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)
... 42 more
怎样使用自定义属性编辑器类型
继续上面的例子,在填充 birthDay 属性时,需要把 string 类型转换为 Date 类型
- 继承 PropertyEditorSupport,自定义 DateEditor 属性编辑器
@Slf4j
public class DateEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd").parse(text));
} catch (Exception e) {
log.warn("DateEditor Convert Fail!");
}
}
}
- 实现 PropertyEditorRegistrar 接口,自定义 DateEditorRegistrar 属性编辑器注册器
public class DateEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new DateEditor());
}
}
- 配置 DateEditorRegistrar,用于 BeanFactory 创建完成后,添加要应用于所有 Bean 创建过程的 PropertyEditorRegistrar
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.ligudo.demo.model.Person">
<property name="birthDay" value="2021-01-01"></property>
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="com.ligudo.demo.spring.DateEditorRegistrar"></bean>
</list>
</property>
</bean>
</beans>
再次运行上面测试用例:
也可以省略步骤2,不再使用属性编辑器注册器,直接把 DateEditor 属性编辑器 注册给 CustomEditorConfigurer :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.ligudo.demo.model.Person">
<property name="birthDay" value="2021-01-01"></property>
</bean>
<!-- <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">-->
<!-- <property name="propertyEditorRegistrars">-->
<!-- <list>-->
<!-- <bean class="com.ligudo.demo.spring.DateEditorRegistrar"></bean>-->
<!-- </list>-->
<!-- </property>-->
<!-- </bean>-->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<value>com.ligudo.demo.spring.DateEditor</value>
</entry>
</map>
</property>
</bean>
</beans>