Spring PropertyEditor如何知道要转换哪个Class属性



我在Spring和Pro Spring中搜索了文档。我不明白CustomerEditorConfigurer是如何知道应该在哪里应用属性转换的。Ex-

我有一个联系人类,它有一个日期变量(jodatTime)我创建了一个ContactPropertyEditor,它扩展了PropertyEditorSupport,并使用setAsText()转换字符串日期。

然后,我进入应用程序并定义CustomerEditorConfigurer,告诉它将jodaTime映射到ContactPropertyEditor。现在,它没有告诉Spring在创建Contact类时使用ContactPropertyEditor进行转换的信息。

所以为了验证我的理论,我创建了另一个类Contact2,它的属性(Date)与Contact相同。当我运行Contact2时,也会发生转换,这有点奇怪。

这是代码示例联系人.java

public class Contact {
private String firstName;
private String lastName;
private DateTime birthDate;
private URL personalSite;

public String toString() {
return "First name: " + getFirstName()
+ " - Last name: " + getLastName()
+ " - Birth date: " + getBirthDate()
+ " - Personal site: " + getPersonalSite();
}
// Getter/setter methods omitted
public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public String getLastName() {
    return lastName;
}
public void setLastName(String lastName) {
    this.lastName = lastName;
}
public DateTime getBirthDate() {
    return birthDate;
}
public void setBirthDate(DateTime birthDate) {
    this.birthDate = birthDate;
}
public URL getPersonalSite() {
    return personalSite;
}
public void setPersonalSite(URL personalSite) {
    this.personalSite = personalSite;
}
}

联系人属性编辑器.java导入java.beans.PropertyEditorSupport;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.stereotype.Component;

public class ContactPropertEditor extends PropertyEditorSupport{
private DateTimeFormatter dateTimeFormatter;
public ContactPropertEditor(String formatPattern){
    System.out.println("In the constructor");
    dateTimeFormatter=DateTimeFormat.forPattern(formatPattern);
}
public void setAsText(String text) throws IllegalArgumentException{
    System.out.println("Setting the value of " + text);
    setValue(DateTime.parse(text, dateTimeFormatter));
}
}

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"         xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"     xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.dinesh"></context:component-scan>
<context:annotation-config />
<!-- This holds the property values and formats -->
<context:property-placeholder location="classpath:application.properties" />
<bean class="com.dinesh.PropertyEditor.ContactPropertEditor" id="contactPropertEditor">
    <constructor-arg><value>"yyyy-MM-dd"</value></constructor-arg>
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="org.joda.time.DateTime">
                <ref local="contactPropertEditor" />
            </entry>
        </map>
    </property>
</bean>
<bean id="clarence" class="com.dinesh.PropertyEditor.Contact"
    p:firstName="Clarence" p:lastName="Ho" p:birthDate="1970-12-31"
    p:personalSite="http://www.clarence.com" />

<bean id="contact2" class="com.dinesh.PropertyEditor.Customer2"
    p:firstName="Clarence" p:lastName="Ho" p:birthDate="1970-12-31"
    p:personalSite="http://www.clarence.com" /> 

现在,正如您所看到的,我所做的只是告诉org.springframework.beans.factory.config.CustomEditorConfigurer,我的property转换逻辑是contactPropertEditor类。我没有告诉Spring将此应用于Contact.java类。

魔法是怎么发生的。

在Spring文档中,它说了一些其他有意义的内容。

Spring文档有一个名为ExoticType()的类,该类具有name属性。一个名为ExoticTypeEditor的编辑器calss用于将名称更改为大写,并且应用程序上下文xml是明确的

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
 <property name="customEditors">
   <map>
     <entry key="example.ExoticType" value="example.ExoticTypeEditor"/>
   </map>
 </property>

在这里,我可以看到我正在告诉CustomEditorConfigurer使用ExoticTypeEditor对类ExoticType应用转换,但Pro-Spring 3中的情况并非如此。我在Contact Example中尝试了同样的操作,但出现了错误。

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="com.dinesh.PropertyEditor.Contact">
                <ref local="contactPropertEditor" />
            </entry>
        </map>
    </property>
</bean>

错误:无法将属性"birthDate"的类型[java.lang.String]的值转换为所需的类型[org.joda.time.DateTime]:找不到匹配的编辑器或转换策略

知道我错过了什么吗?

当您在应用程序上下文中注册PropertyEditor时,您将提供从String到某种类型的转换器,在您的情况下是JodaTime类型。持有类型(Contact)的bean并不重要。应用程序上下文将在需要在anybean上将JodaTime类型的属性设置为String的任何时候使用ContactPropertyEditor编辑器。

所以ContactPropertyEdit是个坏名字。它应该是JodaTimePropertyEditor。

如果您想要一个真正的ContactPropertyEditor,它应该将Strings转换为Contacts。例如:

<bean id="someBeanHoldingAContact" class="someBeanClass">
<property name="contact" value="Hendrix, Jimi, 1942-11-27, http://www.jimihendrix.com" />
</bean>

ContactPropertyEditor应该使用字符串值来创建联系人。

魔术org.springframework.beans.BeanWrapperImp类中。请参阅javadoc

如果人们在谷歌上搜索这个标题,试图找到如何在转换时动态获取目标类,你可以尝试使用ConditionalGenericConverter。

相关部件:

检查每个转换请求:

    @Override
public Set<ConvertiblePair> getConvertibleTypes() {
    return null;//accept everything
}

如果您处理此情况或将其传递给弹簧默认转换器,请检查何时请求转换:

 @Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
       if (sourceType.getType().equals(String.class) && MyInterface.class.isAssignableFrom(targetType.getType()))
        return true; 
return false;
}

处理转换:

@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {    
output = targetType.getType().newInstance();
//do whatever is required here
return output;
}

最新更新