spring4.0之后,自定义属性编辑器的配置变化

[html] view plain copy
  1. 问题:spring中注入时间日期(java.util.Date)类型的属性的时候需要进行类型转换,因为spring不能直接注入Date类型。之前学习spring的时候是学的spring 2.5的版本,但是今天把spring的包都换成了spring 4.2 的,发现之前的出现错误。  

具体的错误信息如下:

[html] view plain copy
  1. log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).  
  2. log4j:WARN Please initialize the log4j system properly.  
  3. Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customEditorConfigurer' defined in file [E:\Workspaces\MyEclipse 10\spring_utildate\bin\applicationContext-beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.LinkedHashMap] to required type [java.util.Map] for property 'customEditors'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [com.zm.bean.UtilDatePropertyEditor] to required type [java.lang.Class] for property 'customEditors[java.util.Date]': PropertyEditor [org.springframework.beans.propertyeditors.ClassEditor] returned inappropriate value of type [com.zm.bean.UtilDatePropertyEditor]  
  4.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)  
  5.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)  
  6.     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)  
  7.     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)  
  8.     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)  
  9.     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)  
  10.     at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:171)  
  11.     at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:678)  
  12.     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:520)  
  13.     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)  
  14.     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)  
  15.     at com.zm.test.Test.main(Test.java:11)  
  16. Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.LinkedHashMap] to required type [java.util.Map] for property 'customEditors'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [com.zm.bean.UtilDatePropertyEditor] to required type [java.lang.Class] for property 'customEditors[java.util.Date]': PropertyEditor [org.springframework.beans.propertyeditors.ClassEditor] returned inappropriate value of type [com.zm.bean.UtilDatePropertyEditor]  
  17.     at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:596)  
  18.     at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603)  
  19.     at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:204)  
  20.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1527)  
  21.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1486)  
  22.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)  
  23.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)  
  24.     ... 11 more  
  25. Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [com.zm.bean.UtilDatePropertyEditor] to required type [java.lang.Class] for property 'customEditors[java.util.Date]': PropertyEditor [org.springframework.beans.propertyeditors.ClassEditor] returned inappropriate value of type [com.zm.bean.UtilDatePropertyEditor]  
  26.     at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:298)  
  27.     at org.springframework.beans.TypeConverterDelegate.convertToTypedMap(TypeConverterDelegate.java:655)  
  28.     at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:222)  
  29.     at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)  
  30.     ... 17 more  
经过查看日志得到的提示是,自定义的编辑器类型与要求的类型不匹配。由于之前一点代码没有改动,只是将spring 2.0 的包换成了spring 4.0的包,因此,感觉应该不是代码的问题。只能说明是spring 4.0的新特性所致。于是开始跟踪源码,最后终于发现了“惊天大幂幂”。。。

Spring 2.0的配置

bean类:
[html] view plain copy
  1. package com.zm.bean;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class Bean1 {  
  6.     private Date dateValue;  
  7.   
  8.     public Date getDateValue() {  
  9.         return dateValue;  
  10.     }  
  11.   
  12.     public void setDateValue(Date dateValue) {  
  13.         this.dateValue = dateValue;  
  14.     }  
  15.       
  16. }  
自定义属性编辑器类(UtilDatePropertyEditor):

[html] view plain copy
  1. package com.zm.bean;  
  2.   
  3. import java.beans.PropertyEditorSupport;  
  4. import java.text.SimpleDateFormat;  
  5. import java.text.ParseException;  
  6. import java.util.Date;  
  7.   
  8. public class UtilDatePropertyEditor extends PropertyEditorSupport {  
  9.       
  10.     private String format="yyyy-MM-dd";  
  11.       
  12.     @Override  
  13.     public void setAsText(String text) throws IllegalArgumentException {  
  14.         // TODO Auto-generated method stub  
  15.         System.out.println("UtilDatePropertyEditor.setAsText() -- text=" + text);  
  16.           
  17.         SimpleDateFormat sdf = new SimpleDateFormat(format);  
  18.         try{  
  19.             Date d = sdf.parse(text);  
  20.             this.setValue(d);  
  21.         }catch (ParseException e) {  
  22.             // TODO Auto-generated catch block  
  23.             e.printStackTrace();  
  24.         }  
  25.     }  
  26.   
  27.     public void setFormat(String format) {  
  28.         this.format = format;  
  29.     }  
  30.       
  31. }  

相关配置:

[html] view plain copy
  1. <span style="white-space:pre">    span>  
  2.     <bean id="bean1" class="com.zm.bean.Bean1">  
  3.          <property name="dateValue" value="2016-08-20"/>  
  4.     bean>  
  5.       
  6.     <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">  
  7.         <property name="customEditors">  
  8.             <map>  
  9.                 <entry key="java.util.Date" >  
  10.                     <bean class="com.zm.bean.UtilDatePropertyEditor">  
  11.                         <property name="format" value="yyyy-MM-dd"/>  
  12.                     bean>  
  13.                 entry>  
  14.             map>  
  15.         property>  
  16.     bean>  

Spring 4.0的配置

相关配置:
[html] view plain copy
  1. <span style="white-space:pre">    span>  
  2.     <bean id="bean1" class="com.zm.bean.Bean1">  
  3.          <property name="dateValue" value="2016-08-20"/>  
  4.     bean>  
  5.       
  6.     <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">  
  7.         <property name="customEditors">  
  8.             <map>  
  9.                 <entry key="java.util.Date" value="com.zm.bean.UtilDatePropertyEditor"/>  
  10.             map>  
  11.         property>  
  12.     bean>  

对比上面的配置可以发现,唯一的区别在于,在配置customEditors属性的时候,spring2.0配置的的value是一个,而spring4.0配置的的value是类名。
 查看源码可以发现customEditors的类型,在spring2.0 中是Map类型,key和value的类型并不确定,但是底层处理的时候,key的类型必须是Class类型,而value是一个注入的bean;在spring4.0中,customEditors的类型变为了Map, Class>, 也就是说,key和value的类型已经确定为Class类型。

你可能感兴趣的:(spring)