在spring2.0中使用自定义属性编辑器

当以一个字符串值来设置bean属性时,Spring IoC 容器最终使用标准的JavaBean PropertyEditor来将这些字符串转化成复杂的数据类型。Spring预先注册了一些PropertyEditor(举例来说,将一个以字符串表示的Class转化成Class对象)。除此之外,Java标准的JavaBean PropertyEditor会识别在同一包结构下的类和它对应的命名恰当的Editor,并自动将其作为这个类的的Editor。
比如
Address类有一个PhoneNumber属性
package com.springinaction.propertyeditor;

public class Address {
 private PhoneNumber phoneNumber;

 public PhoneNumber getPhoneNumber() {
  return phoneNumber;
 }

 public void setPhoneNumber(PhoneNumber phoneNumber) {
  this.phoneNumber = phoneNumber;
 }

}
PhoneNumber类:
package com.springinaction.propertyeditor;

public class PhoneNumber {
 private String areaCode;
 private String prefix;
 private String number;

 public PhoneNumber(String areaCode, String prefix, String number) {
  this.areaCode = areaCode;
  this.prefix = prefix;
  this.number = number;
 }

 //省略getter和setter,toString()方法

}
PhoneNumberEditor类:
package com.springinaction.propertyeditor;

import java.beans.PropertyEditorSupport;

public class PhoneNumberEditor extends PropertyEditorSupport {

 @Override
 public void setAsText(String text) throws IllegalArgumentException {
  // TODO Auto-generated method stub
//  super.setAsText(text);
  String stripped = strippedNonNumber(text);
  String areaCode = stripped.substring(0,3);
  String prefix = stripped.substring(3,6);
  String number = stripped.substring(6);
  PhoneNumber phone = new PhoneNumber(areaCode,prefix,number);
  setValue(phone);
 }
 public String strippedNonNumber(String original){
  StringBuffer allNumbers = new StringBuffer();
  for(int i=0;i<original.length();i++){
   char c = original.charAt(i);
   if(Character.isDigit(c)){
    allNumbers.append(c);
   }
  }
  return allNumbers.toString();
 }
}
配置文件:
<?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-2.0.xsd">
 
 
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
 

</beans>
测试代码:
package com.springinaction.propertyeditor;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class PropertyEditorTest {
 public static void main(String[] args) {
  BeanFactory bf = new XmlBeanFactory(new ClassPathResource(
    "com/springinaction/propertyeditor/editor.xml"));
 
  Address address = (Address) bf.getBean("address");
  System.out.println(address.getPhoneNumber());
 }
}
因为PhoneNumber类和PhoneNumberEditor类在同一个包下,不用注册PhoneNumberEditor,就能将字符串类型的800-900-6789转换成PhoneNumber类型。
如果PhoneNumber类相应的编辑器类名不是PhoneNumberEditor,而是别的名字,比如PhoneEditor,上面其它的代码和配置都不变,再运行测试类的时候就会报
java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.springinaction.propertyeditor.PhoneNumber]异常。
要解决这个问题,需要注册自定义的编辑器和将XmlBeanFactory改成ApplicationContext。
可以通过customEditors属性注册编辑器或者通过propertyEditorRegistrars属性注册编辑器。
customEditors属性方式注册:
<?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-2.0.xsd">

 <bean id="customEditorConfigurer"
  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
   <map>
    <entry key="com.springinaction.propertyeditor.PhoneNumber">
     <bean id="phoneEditor" class="com.springinaction.propertyeditor.PhoneEditor">
     </bean>
    </entry>
   </map>
  </property>
 </bean>
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
</beans>
propertyEditorRegistrars属性方式注册:
<?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-2.0.xsd">

 <bean id="editorRegister" class="com.springinaction.propertyeditor.PhoneEditorRegister" />
 <bean id="customEditorConfigurer"
  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="propertyEditorRegistrars">
   <ref bean="editorRegister" />
  </property>
 </bean>
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
</beans>
添加的PhoneEditorRegister类代码如下,它实现了PropertyEditorRegistrar,注册了PhoneEditor。
package com.springinaction.propertyeditor;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;

public class PhoneEditorRegister implements PropertyEditorRegistrar {

 public void registerCustomEditors(PropertyEditorRegistry registry) {
  
  registry.registerCustomEditor(com.springinaction.propertyeditor.PhoneNumber.class,
    new PhoneEditor());
 }

}
测试类修改如下:
package com.springinaction.propertyeditor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class PropertyEditorTest {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext(
    "com/springinaction/propertyeditor/editor.xml");
  Address address = (Address) context.getBean("address");
    System.out.println(address.getPhoneNumber());
 }
}
这时在运行测试类,字符串类型的值800-900-6789就可以成功转换成PhoneNumber类型了,控制台会输出800-900-6789。

你可能感兴趣的:(spring,c,bean,xml,IOC)