/** * Specify the {@link PropertyEditorRegistrar PropertyEditorRegistrars} * to apply to beans defined within the current application context. * <p>This allows for sharing {@code PropertyEditorRegistrars} with * {@link org.springframework.validation.DataBinder DataBinders}, etc. * Furthermore, it avoids the need for synchronization on custom editors: * A {@code PropertyEditorRegistrar} will always create fresh editor * instances for each bean creation attempt. * @see ConfigurableListableBeanFactory#addPropertyEditorRegistrar */ publicvoidsetPropertyEditorRegistrars(PropertyEditorRegistrar[] propertyEditorRegistrars){ this.propertyEditorRegistrars = propertyEditorRegistrars; }
/** * Specify the custom editors to register via a {@link Map}, using the * class name of the required type as the key and the class name of the * associated {@link PropertyEditor} as value. * @see ConfigurableListableBeanFactory#registerCustomEditor */ publicvoidsetCustomEditors(Map<Class<?>, Class<? extends PropertyEditor>> customEditors){ this.customEditors = customEditors; }
@Override publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException { if (this.propertyEditorRegistrars != null) { for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) { beanFactory.addPropertyEditorRegistrar(propertyEditorRegistrar); } } if (this.customEditors != null) { this.customEditors.forEach(beanFactory::registerCustomEditor); } }
if (editor != null && !(convertedValue instanceof String)) { // Not a String -> use PropertyEditor's setValue. // With standard PropertyEditors, this will return the very same object; // we just want to allow special PropertyEditors to override setValue // for type conversion from non-String values to the required type. try { editor.setValue(convertedValue); Object newConvertedValue = editor.getValue(); if (newConvertedValue != convertedValue) { convertedValue = newConvertedValue; // Reset PropertyEditor: It already did a proper conversion. // Don't use it again for a setAsText call. editor = null; } } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", ex); } // Swallow and proceed. } }
Object returnValue = convertedValue;
if (requiredType != null && !requiredType.isArray() && convertedValue instanceof String[]) { // Convert String array to a comma-separated String. // Only applies if no PropertyEditor converted the String array before. // The CSV String will be passed into a PropertyEditor's setAsText method, if any. if (logger.isTraceEnabled()) { logger.trace("Converting String array to comma-delimited String [" + convertedValue + "]"); } convertedValue = StringUtils.arrayToCommaDelimitedString((String[]) convertedValue); }
if (convertedValue instanceof String) { if (editor != null) { // Use PropertyEditor's setAsText in case of a String value. if (logger.isTraceEnabled()) { logger.trace("Converting String to [" + requiredType + "] using property editor [" + editor + "]"); } String newTextValue = (String) convertedValue; // 最终做事的方法 return doConvertTextValue(oldValue, newTextValue, editor); } elseif (String.class == requiredType) { returnValue = convertedValue; } }
return returnValue; }
追踪 doConvertTextValue
1 2 3 4 5 6 7 8 9 10 11 12 13
private Object doConvertTextValue(@Nullable Object oldValue, String newTextValue, PropertyEditor editor){ try { editor.setValue(oldValue); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", ex); } // Swallow and proceed. } editor.setAsText(newTextValue); return editor.getValue(); }