JavaBeans PropertyEditor

主要是学习了解spring如何利用PropertyEditor完成conversion的。参考实现来自网络和spring reference

Spring uses the concept of PropertyEditors to effect the conversion between an Object and a String.

Spring has a number of built-in PropertyEditors to make life easy. Each of those is listed below and they are all located in the org.springframework.beans.propertyeditors package. Most,but not all (as indicated below), are registered by default by BeanWrapperImpl. Where the property editor is configurable in some fashion, you can of course still register your own variant to override the default one:

Spring uses the java.beans.PropertyEditorManager to set the search path for property editors that might be needed

Registering additional custom PropertyEditors
When setting bean properties as a string value, a Spring IoC container ultimately uses standard JavaBeans PropertyEditors to convert these Strings to the complex type of the property
引用
One quite important class in the beans package is the BeanWrapper interface and its corresponding
implementation (BeanWrapperImpl). As quoted from the Javadoc, the BeanWrapper offers
functionality to set and get property values (individually or in bulk), get property descriptors, and to query
properties to determine if they are readable or writable. Also, the BeanWrapper offers support for
nested properties, enabling the setting of properties on sub-properties to an unlimited depth. Then, the
BeanWrapper supports the ability to add standard JavaBeans PropertyChangeListeners and
VetoableChangeListeners, without the need for supporting code in the target class. Last but not
least, the BeanWrapper provides support for the setting of indexed properties. The BeanWrapper
usually isn't used by application code directly, but by the DataBinder and the BeanFactory.
The way the BeanWrapper works is partly indicated by its name: it wraps a bean to perform actions on
that bean, like setting and retrieving properties.


以下是Registered by default by BeanWrapperImpl.

    ByteArrayPropertyEditor
    ClassEditor
    CustomBooleanEditor
    CustomCollectionEditor
    CustomNumberEditor
    FileEditor
    LocaleEditor
    InputStreamEditor
    PatternEditor
    PropertiesEditor
    StringTrimmerEditor
    URLEditor

not Registered by default by BeanWrapperImpl.
CustomDateEditor

Spring对于注册自定义PropertyEditor提供了完善的支持;唯一的缺点是java.beans.PropertyEditor接口拥有许多的方法,很多方法实际上与属性类型转换没有关系。幸运的是Spring提供了PropertyEditorSupport类,你的PropertyEditors可以扩展这个类,这样你就仅仅需要实现一个方法:setAsText()。
javabean:
public class User {   
	    private int u_id;   
	    private String userName;   
	    private Set<String> Favorates;   
	    private List<String>lovers;    
	    private Map<String, Score> score;   
	    private Properties MOU;   
	    private Date birthday;   
	    private Resource pic;   
	    public void setU_id(int u_id) {   
	        this.u_id = u_id;   
	    }   
	  
	    public void setUserName(String userName) {   
	        this.userName = userName;   
	    }   
	  
	    public void setFavorates(Set<String> favorates) {   
	        Favorates = favorates;   
	    }   
	  
	    public void setScore(Map<String, Score> score) {   
	        this.score = score;   
	    }   
	  
	    public void setMOU(Properties mou) {   
	        MOU = mou;   
	    }   
	  
	    public void setBirthday(Date birthday) {   
	        this.birthday = birthday;   
	    }   
	  
	    public void setPic(Resource pic) {   
	        this.pic = pic;   
	    }   
	  
	    public Resource getPic() {   
	        return pic;   
	    }   
	  
	    public int getU_id() {   
	        return u_id;   
	    }   
	  
	    public String getUserName() {   
	        return userName;   
	    }   
	  
	    public Set<String> getFavorates() {   
	        return Favorates;   
	    }   
	  
	    public Map<String, Score> getScore() {   
	        return score;   
	    }   
	  
	    public Properties getMOU() {   
	        return MOU;   
	    }   
	  
	    public Date getBirthday() {   
	        return birthday;   
	    }   
	  
	    public List<String> getLovers() {   
	        return lovers;   
	    }   
	  
	    public void setLovers(List<String> lovers) {   
	        this.lovers = lovers;   
	    }   
	  


定义自己的editor
public class DatePropertyEditor extends PropertyEditorSupport {

	private String format = "yyyy-MM-dd";
	public String getFormat() {
		return format;
	}
	public void setFormat(String format) {
		this.format = format;
	}
	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		SimpleDateFormat df = new SimpleDateFormat(format);
		try {
			Date date = df.parse(text);
			this.setValue(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

}


配置文件
<!-- 基本类型 -->
	<bean class="com.spring.propertTest.User" id="user">
		<property name="userName" value="fisher"></property>
		<property name="u_id" value="1"></property>
		<!-- list以及数组类型 -->
		<property name="lovers">
			<list>
				<value>susan</value>
				<value>Angle</value>
			</list>
		</property>
		<!-- set集合,与list配置雷同 -->
		<property name="favorates">
			<set>
				<value>computer</value>
				<value>basketball</value>
			</set>
		</property>
		<!-- map集合以及引用类型的注入配置 -->
		<property name="score">
			<map>
				<entry key="电脑" value-ref="score"></entry>
			</map>
		</property>
		<!-- properties的注入配置 -->
		<property name="MOU">
			<props>
				<prop key="today">rain!</prop>
				<prop key="tomorrow">nice weather!</prop>
			</props>
		</property>
		<property name="birthday" value="1987-2-12"></property>
		<property name="pic" value="file:////e:/J2EE技术.jpg"></property>  
	</bean>
	<!--Score-->
	<bean class="com.spring.propertTest.Score" id="score">
		<property name="s_id" value="1"></property>
		<property name="score" value="90"></property>
	</bean>
	<!-- dateEditor -->
	<bean class="com.spring.propertTest.DatePropertyEditor" id="dateEditor"></bean>

	<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">  
     <!--customEditor是map集合类型-->  
    <property name="customEditors">  
        <map>  
           <!--key是代表属性类型,value这里是引用自定义的dateEditor类-->  
            <entry key="java.util.Date" value-ref="dateEditor">  
            </entry>  
        </map>  
    </property>  
</bean>  	


引用
在上面的配置文件中你应该注意三个地方:首先是使用Map类型的customEditors属性将自定义PropertyEditors注入CustomEditorConfigurer。第二点是Map表现得每一个表现单一PropertyEditor的entry的key应该是这个PropertyEditor使用的类的限定名。最后一点是我们使用了一个匿名bean用来表示Map条目的值。没有其他的bean需要访问这个bean,所以他不需要名字,你可以将它声明在<entry>标签中。


测试
public static void main(String[] args) throws IOException {
		ApplicationContext factory=new ClassPathXmlApplicationContext("beans.xml"); 
	    User user = (User) factory.getBean("user");   
	    System.out.println(user.getBirthday());
	    Resource res = user.getPic();   
	    InputStream is = res.getInputStream();   
	    byte[] by = new byte[is.available()];   
	    is.read(by);   
	    OutputStream os = new FileOutputStream("e:/rbk.jpg");   
	    os.write(by);   
	    os.close();   
	}

或者可以这样写:
public static void main(String[] args) throws IOException {
		ConfigurableListableBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));  
		CustomEditorConfigurer configurer =(CustomEditorConfigurer)factory.getBean("customEditorConfigurer");  
		configurer.postProcessBeanFactory(factory);  
	    User user = (User) factory.getBean("user");   
	    System.out.println(user.getBirthday());
	    Resource res = user.getPic();   
	    InputStream is = res.getInputStream();   
	    byte[] by = new byte[is.available()];   
	    is.read(by);   
	    OutputStream os = new FileOutputStream("e:/rbk.jpg");   
	    os.write(by);   
	    os.close();  
	}

引用
CustomEditorConfigurer.postProcessBeanFactory()的调用。这是在Spring中注册自定义editor的地方。应该在访问任何需要使用自定义PropertyEditors的beans之前调用它。


还有一种自定义PropertyEditor的注册方式,如下所示:
public static void main(String[] args) throws IOException {
		ConfigurableListableBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));   
		 factory.addPropertyEditorRegistrar(new PropertyEditorRegistrar(){
			 public void registerCustomEditors(PropertyEditorRegistry registry) {  
			      registry.registerCustomEditor(java.util.Date.class,new DatePropertyEditor());  
			 } 
		 });
	    User user = (User) factory.getBean("user");   
	    System.out.println(user.getBirthday());
	    Resource res = user.getPic();   
	    InputStream is = res.getInputStream();   
	    byte[] by = new byte[is.available()];   
	    is.read(by);   
	    OutputStream os = new FileOutputStream("e:/rbk.jpg");   
	    os.write(by);   
	    os.close();   
	}

引用
使用自定义PropertyEditor最复杂的部分是注册过程,有两种方法可以在Spring中注册你的PropertyEditor。第一种方法调用ConfigurableBeanFactory.addPropertyEditorRegistrar()并且传递PropertyEditorRegistrar的实现,在PropertyEditorRegistrar.registerCustomEditors方法中注册PropertyEditor实现。

第二种方法是首选的。在BeanFactory配置中定义一个CustomEditorConfigurer类型的bean,在这个bean的Map类型的属性中指定editors。此外,你可以使用PropertyEditorRegistrar类型的bean的list来使用自定义PropertyEditors Map。The main benefit of using the implementation of the PropertyEditorRegistrar is the MVC framework, where you can use your PropertyEditorRegistrar bean’s registerCustomEditors in the initBinder method.

你可能感兴趣的:(spring,xml,bean,mvc,OS)