我们可以自定义属性编辑器对类中的实例对象赋值,通过string类型值转换成对象类型值进行赋值。当我们使用下列方式注册时:
<bean id="PropertyEditorConfigurer1"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="renchaofeng_propertyEditor.Education" value="renchaofeng_propertyEditor.TestPropertyEditor"/>
</map>
</property>
</bean>
上面方式把我们自己定义的属性编辑器renchaofeng_propertyEditor.TestPropertyEditor注入到org.springframework.beans.factory.config.CustomEditorConfigurer的customEditors属性中,就可以达到转换的效果,那么原理流程是怎样的呢?如下:
org.springframework.beans.factory.config.CustomEditorConfigurer实现了BeanFactoryPostProcessor接口,所以会实现postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法,在此方法中代码如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertyEditorRegistrars != null) {
for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
beanFactory.addPropertyEditorRegistrar(propertyEditorRegistrar);
}
}
if (this.customEditors != null) {//此处集合customEditors中有我们的属性编辑器renchaofeng_propertyEditor.TestPropertyEditor
for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {
Class<?> requiredType = entry.getKey();
Class<? extends PropertyEditor> propertyEditorClass = entry.getValue();
beanFactory.registerCustomEditor(requiredType, propertyEditorClass);//把我们自定义属性编辑器注册入beanFactory中以备后续使用
}
}
}
上面是注入过程,下面在什么怎么取出使用呢?答案如下: 在bean的实例化过程中使用,在AbstractBeanFactory类中创建bean方法中,如下:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//......前面源码省略.....
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);//在此处进行获取我们自定义属性编辑器
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
进入convertIfNecessary中一路点击下去进入类TypeConverterSupport中的方法doConvert,如下:
private <T> T doConvert(Object value, Class<T> requiredType, MethodParameter methodParam, Field field)
throws TypeMismatchException {
try {
if (field != null) {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
}
else {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);//通过此方法进入点击进去
}
}
catch (ConverterNotFoundException ex) {
throw new ConversionNotSupportedException(value, requiredType, ex);
}
catch (ConversionException ex) {
throw new TypeMismatchException(value, requiredType, ex);
}
catch (IllegalStateException ex) {
throw new ConversionNotSupportedException(value, requiredType, ex);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchException(value, requiredType, ex);
}
}
点击进去进入类TypeConverterDelegate中找到方法convertIfNecessary,如下:
/**
* Convert the value to the required type (if necessary from a String),
* for the specified property.
* @param propertyName name of the property
* @param oldValue the previous value, if available (may be {@code null})
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* (or {@code null} if not known, for example in case of a collection element)
* @param typeDescriptor the descriptor for the target property or field
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
@SuppressWarnings("unchecked")
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// Custom editor for this type?
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);//此处就会查找取出我们自定义的属性编辑器进行使用
ConversionFailedException conversionAttemptEx = null;
// No custom editor but custom ConversionService specified?
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
try {
return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
}
catch (ConversionFailedException ex) {
// fallback to default conversion logic below
conversionAttemptEx = ex;
}
}
}
Object convertedValue = newValue;
//.....后面源码省略。。。。。
}
通过debug调试取出我们的属性编辑器如下: