`

(重拾)Spring之属性编辑器

 
阅读更多
因为XmlBeanFactory为BeanFactory的实例,用户需要手工调用registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass)方法注册自定义属性编辑器,Spring属性编辑器的注册方式不支持属性的注入,只能通过需要转化的类型和对应的属性编辑器类型,如此便不能往属性编辑器中传递参数了,如何初始化信息?
package org.springframework.beans.factory.xml.support;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class DatePropertyEditor extends PropertyEditorSupport {

	private List<String> formats; 
	
	public void setFormats(List<String> formats) {
		this.formats = formats;
	}
	
	public DatePropertyEditor(){
		formats = new ArrayList<String>();
		formats.add("yyyy-MM-dd");
		formats.add("yyyy-MM-dd HH:mm:ss");
	}

	@Override
	public void setAsText(String text) throws IllegalArgumentException { 
		try {
			SimpleDateFormat sdf = null; 
			if(text.length() == 10){
				sdf = new SimpleDateFormat((String)formats.get(0));
			}else if(text.length() == 19){
				sdf = new SimpleDateFormat((String)formats.get(1));
			} 
			Date date = sdf.parse(text); // 获取时间信息
			this.setValue(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}


}

可以放在默认构造函数中,因为默认Spring会初始化属性编辑器,所以会默认调用.
在Spring初始化XmlBeanFactory的时候,初始化属性编辑器即可
beanFactory.registerCustomEditor(java.util.Date.class, DatePropertyEditor.class); 

如此,当遇到对象类型为Date,注入的类型为String的时候,会调用这个方法.

但是使用上面的方法注册进去,参数是不会初始化的,因为其注册是类型.
所以请使用PropertyEditorRegistrars
PropertyEditorRegistrar registrar =new PropertyEditorRegistrar() {
			public void registerCustomEditors(PropertyEditorRegistry registry) {
				DatePropertyEditor dpe = new DatePropertyEditor();
				List<String> formats = new ArrayList<String>();
				formats.add("yyyy-MM-dd");
				formats.add("yyyy-MM-dd HH:mm:ss");
				dpe.setFormats(formats);
				registry.registerCustomEditor(Date.class, dpe);
			}
		};
		xct.beanFactory.addPropertyEditorRegistrar(registrar);


这种属性编辑器使用起来比较麻烦[XmlBeanFactory不支持xml注册的方式],而且也不够灵活[输入类型只支持String,而且也很难分享使用,比如我页面等地方的类型转换].

当然Spring对于属性编辑器还是支持的PropertyEditorRegistrySupport,比如BeanWrapperImpl,不过可以指定registerDefaultEditors.[true:引入默认的属性编辑器]

默认的属性编辑器如下:
private void createDefaultEditors() {
		this.defaultEditors = new HashMap<Class<?>, PropertyEditor>(64);

		// Simple editors, without parameterization capabilities.
		// The JDK does not contain a default editor for any of these target types.
		this.defaultEditors.put(Charset.class, new CharsetEditor());
		this.defaultEditors.put(Class.class, new ClassEditor());
		this.defaultEditors.put(Class[].class, new ClassArrayEditor());
		this.defaultEditors.put(Currency.class, new CurrencyEditor());
		this.defaultEditors.put(File.class, new FileEditor());
		this.defaultEditors.put(InputStream.class, new InputStreamEditor());
		this.defaultEditors.put(InputSource.class, new InputSourceEditor());
		this.defaultEditors.put(Locale.class, new LocaleEditor());
		this.defaultEditors.put(Pattern.class, new PatternEditor());
		this.defaultEditors.put(Properties.class, new PropertiesEditor());
		this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
		this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
		this.defaultEditors.put(URI.class, new URIEditor());
		this.defaultEditors.put(URL.class, new URLEditor());
		this.defaultEditors.put(UUID.class, new UUIDEditor());

		// Default instances of collection editors.
		// Can be overridden by registering custom instances of those as custom editors.
		this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
		this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
		this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
		this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
		this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));

		// Default editors for primitive arrays.
		this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
		this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());

		// The JDK does not contain a default editor for char!
		this.defaultEditors.put(char.class, new CharacterEditor(false));
		this.defaultEditors.put(Character.class, new CharacterEditor(true));

		// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
		this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
		this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));

		// The JDK does not contain default editors for number wrapper types!
		// Override JDK primitive number editors with our own CustomNumberEditor.
		this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
		this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
		this.defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
		this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
		this.defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
		this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
		this.defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
		this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
		this.defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
		this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
		this.defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
		this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
		this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
		this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));

		// Only register config value editors if explicitly requested.
		if (this.configValueEditorsActive) {
			StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
			this.defaultEditors.put(String[].class, sae);
			this.defaultEditors.put(short[].class, sae);
			this.defaultEditors.put(int[].class, sae);
			this.defaultEditors.put(long[].class, sae);
		}
	}


属性编辑器基本上支持基本类型(int,long,float,double等).

这是以前Spring的使用方法属性编辑器,Spring3.0之后的版本[我是参阅spring3.0源码].
都是使用Converter,为了兼容以前的版本,属性编辑器也支持使用,spring的逻辑是先属性编辑器,如果没有找到,则会检测类型转换器,类型转化器针对的是全局的。只会注册一次,而属性编辑器会在每一个BeanWrapper中注册.
优先级如下:
if (editor == null && conversionService != null && convertedValue != null && typeDescriptor != null) {
			TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
			TypeDescriptor targetTypeDesc = typeDescriptor;
			if (conversionService.canConvert(sourceTypeDesc, targetTypeDesc)) {
				try {
					return (T) conversionService.convert(convertedValue, sourceTypeDesc, targetTypeDesc);
				}
				catch (ConversionFailedException ex) {
					// fallback to default conversion logic below
					firstAttemptEx = ex;
				}
			}
		}

		// Value not of required type?
		if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
			if (requiredType != null && Collection.class.isAssignableFrom(requiredType) && convertedValue instanceof String) {
				TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor();
				if (elementType != null && Enum.class.isAssignableFrom(elementType.getType())) {
					convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
				}
			}
			if (editor == null) {
				editor = findDefaultEditor(requiredType, typeDescriptor);
			}
			convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
		}

如果编辑器中没有找到匹配的类型,才会执行convert

如此使用ApplicationContext,则不需要这么麻烦了,只需要xml配置即可
	<bean id="customEditorConfigurer"
		class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry key="java.util.Date">
					<bean class="org.springframework.beans.factory.xml.support.DatePropertyEditor">
						设置时间格式
						<property name="formats">  
							<list>
								<value>yyyy-MM-dd</value>
								<value>yyyy-MM-dd HH:mm:ss</value>
							</list>
						</property> 
					</bean>
				</entry>
			</map>
		</property>
		<property name="propertyEditorRegistrars">
			<set>
				 <ref bean="propertyEditorRegistrar" />
			</set>
		</property> 
	</bean>
	
	<bean id="propertyEditorRegistrar"
		class="org.springframework.context.DDPropertyRegister"> 
	</bean>

我这里定义了两种方式,可以通过Registar注册,也可以直接通过customEditors注册自定义的属性编辑器,但是我不推荐这么做,毕竟属性编辑器会在每一个spring bean的初始化。

所以在spring3.0出了一个叫convert的类型转换器,在属性编辑器不存在的时候,则会调用类型转换器,针对全局的。
分享到:
评论

相关推荐

    spring 自定义属性编辑器

    在Spring框架中,属性编辑器(PropertyEditor)是一种强大的工具,允许我们自定义类型转换过程。当我们需要将字符串形式的数据转换为Java对象时,属性编辑器就发挥了关键作用。例如,从请求参数或配置文件中读取的...

    spring中的自定义属性编辑器

    在Spring框架中,属性编辑器(PropertyEditor)扮演着至关重要的角色。它们是JavaBeans规范的一部分,用于在Java对象和其字符串表示之间进行转换。在Spring中,我们可以通过自定义属性编辑器来处理特定类型的值,...

    spring2.0(三) 自定义属性编辑器

    在Spring 2.0框架中,自定义属性编辑器(Custom Property Editor)是一个重要的功能,它允许开发者扩展Spring的默认属性绑定机制,以处理特定类型的转换。本文将深入探讨这一特性,结合源码分析和实际应用,帮助你...

    Spring学习笔记(11)----自定义属性编辑器

    在Spring框架中,属性编辑器(PropertyEditor)扮演着至关重要的角色。它们是JavaBeans规范的一部分,用于在Java对象和字符串之间进行数据转换。在Spring中,属性编辑器被广泛应用于IoC容器,用于处理配置文件中的...

    浅谈Spring的属性编辑器的使用

    在Spring框架中,属性编辑器(PropertyEditor)是一个关键组件,它负责将配置文件中非标准格式的数据转换为JavaBean的可识别类型。属性编辑器是基于JavaBeans规范的,因此理解这个概念需要先了解JavaBean和JavaBeans...

    spring bean 属性总结

    在Spring中,核心概念之一就是Bean,它是一个简单的Java对象,由Spring IoC容器管理。Spring通过XML配置文件或注解来定义、配置和管理Beans。下面将深入探讨`&lt;beans&gt;`、`&lt;bean&gt;`及其属性,以及其他相关的配置元素。 ...

    spring 的属性管理

    总结起来,Spring的属性管理是其强大的功能之一,它提供了灵活多样的方式来管理应用的配置,确保了配置的可扩展性、可维护性和可管理性。开发者可以根据项目需求选择适合的方式来处理和注入属性,提高开发效率和应用...

    spring 普通属性注入

    在Spring框架中,属性注入是核心特性之一,它允许我们通过依赖注入(Dependency Injection, DI)来管理对象的属性,而不是让对象自行创建或查找它们的依赖。这有助于提高代码的可测试性、可维护性和解耦性。下面将...

    spring自定义编辑器

    ### Spring自定义编辑器详解 #### 一、引言 在Spring框架中,自定义编辑器主要用于处理数据类型的转换问题,特别是在将用户输入的数据转换为Java对象时非常有用。例如,用户通过表单提交了一个日期格式的字符串,...

    springmvc自定义属性编辑器和参数解析器

    在Spring MVC框架中,属性编辑器(PropertyEditor)和参数解析器(HandlerMethodArgumentResolver)是两个关键组件,用于处理数据转换和模型绑定的过程。它们是实现灵活性和扩展性的重要手段,尤其在处理用户输入...

    spring编辑器

    标题 "spring编辑器" 暗示我们讨论的是与Spring框架相关的开发工具,可能是用于编辑、配置或调试Spring应用的工具。描述中的链接指向了一篇2019年的博客文章,但无法直接访问以获取详细信息。不过,我们可以基于...

    spring 属性参考与自动绑定

    《Spring属性参考与自动绑定详解》 在Java的Spring框架中,属性参考和自动绑定是两个重要的概念,它们为开发者提供了灵活且强大的依赖注入机制。本文将深入解析这两个概念,并通过示例代码来阐述其工作原理。 ### ...

    自定义属性编辑及Spring处理器映射

    java中的属性编辑器详细说明及Spring中AnnotationMethodHandlerAdapter说明和DefaultAnnotationHandlerMapping的说明及用法

    Spring注解注入属性

    ### Spring注解注入属性 #### 一、传统方式与注解方式对比 在Spring框架中,依赖注入(DI)是一种核心的设计模式,用于促进松耦合的系统设计,使得组件之间的依赖关系可以在运行时动态地建立,而不是在编译时硬...

    知识共享-Spring注入属性值案例(雷惊风).

    Spring的核心特性之一就是依赖注入,它简化了组件之间的耦合度,提高了代码的可维护性和可测试性。 #### 二、属性值注入概述 在Spring框架中,属性值注入是一种常见的依赖注入方式,用于设置一个Bean的属性值。...

    Spring属性注入

    在Spring中,属性注入(Property Injection)是一种重要的功能,它允许开发者在不直接创建对象的情况下设置对象的属性,从而实现了松耦合和更好的可测试性。 **XML方式的属性注入** 1. **Set注入**:这是Spring ...

    编码剖析Spring装配基本属性的原理

    在Spring框架中,装配是核心概念之一,它允许开发者声明性地配置和组合应用程序组件。本文将深入探讨Spring装配基本属性的原理,帮助你更好地理解如何在代码中使用和配置这些属性。 首先,Spring装配的基本方式有两...

    Spring视频教程(1)

    此外,"009_Spring属性编辑器.avi"和"011_Spring属性编辑器_日期格式可配置_多文件读取方式.avi"将讲解Spring属性编辑器的用法,如何处理复杂类型的属性注入,如日期格式化和文件操作。 "010_上午内容回顾.avi"是对...

    spring集合属性

    在Spring框架中,集合属性(Collections Property)是一个重要的概念,它允许我们配置bean的属性为集合类型,如List、Set、Map等。这些集合可以由Spring容器动态填充,提供了极大的灵活性和可配置性,使得我们可以...

Global site tag (gtag.js) - Google Analytics