spring4.0之後,自定義屬性編輯器的配置變化
阿新 • • 發佈:2019-02-03
問題:spring中注入時間日期(java.util.Date)型別的屬性的時候需要進行型別轉換,因為spring不能直接注入Date型別。之前學習spring的時候是學的spring 2.5的版本,但是今天把spring的包都換成了spring 4.2 的,發現之前的出現錯誤。
具體的錯誤資訊如下:
經過檢視日誌得到的提示是,自定義的編輯器型別與要求的型別不匹配。由於之前一點程式碼沒有改動,只是將spring 2.0 的包換成了spring 4.0的包,因此,感覺應該不是程式碼的問題。只能說明是spring 4.0的新特性所致。於是開始跟蹤原始碼,最後終於發現了“驚天大冪冪”。。。log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. 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] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:171) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:678) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:520) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.zm.test.Test.main(Test.java:11) 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] at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:596) at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603) at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:204) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1527) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1486) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ... 11 more 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] at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:298) at org.springframework.beans.TypeConverterDelegate.convertToTypedMap(TypeConverterDelegate.java:655) at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:222) at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576) ... 17 more
Spring 2.0的配置
bean類:自定義屬性編輯器類(UtilDatePropertyEditor):package com.zm.bean; import java.util.Date; public class Bean1 { private Date dateValue; public Date getDateValue() { return dateValue; } public void setDateValue(Date dateValue) { this.dateValue = dateValue; } }
package com.zm.bean; import java.beans.PropertyEditorSupport; import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Date; public class UtilDatePropertyEditor extends PropertyEditorSupport { private String format="yyyy-MM-dd"; @Override public void setAsText(String text) throws IllegalArgumentException { // TODO Auto-generated method stub System.out.println("UtilDatePropertyEditor.setAsText() -- text=" + text); SimpleDateFormat sdf = new SimpleDateFormat(format); try{ Date d = sdf.parse(text); this.setValue(d); }catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void setFormat(String format) { this.format = format; } }
相關配置:
<span style="white-space:pre"> </span><!-- 配置bean1 -->
<bean id="bean1" class="com.zm.bean.Bean1">
<property name="dateValue" value="2016-08-20"/>
</bean>
<!-- 配置自定義屬性編輯器 -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date" >
<bean class="com.zm.bean.UtilDatePropertyEditor">
<property name="format" value="yyyy-MM-dd"/>
</bean>
</entry>
</map>
</property>
</bean>
Spring 4.0的配置
相關配置:<span style="white-space:pre"> </span><!-- 配置bean1 -->
<bean id="bean1" class="com.zm.bean.Bean1">
<property name="dateValue" value="2016-08-20"/>
</bean>
<!-- 配置自定義屬性編輯器 -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date" value="com.zm.bean.UtilDatePropertyEditor"/>
</map>
</property>
</bean>
對比上面的配置可以發現,唯一的區別在於,在配置customEditors屬性的時候,spring2.0配置的<entry>的value是一個<bean>,而spring4.0配置的<entry>的value是類名。 檢視原始碼可以發現customEditors的型別,在spring2.0 中是Map型別,key和value的型別並不確定,但是底層處理的時候,key的型別必須是Class型別,而value是一個注入的bean;在spring4.0中,customEditors的型別變為了Map<Class<?>, Class<? extends PropertyEditor>>, 也就是說,key和value的型別已經確定為Class型別。