-
PropertyEditorRegistry 属性编辑器注册表
-
封装了注册 JavaBeans PropertyEditors 的方法
//注册给定类型的所有属性的自定义属性编辑器 void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor);
//如果属性path是一个array/Collection,这里的requireType应该是其元素的类型 void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor);
//找到一个指定类型和属性的属性编辑器 @Nullable PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath);
-
-
PropertyEditorRegistrySupport 属性便捷器注册支持
-
是 PropertyEditorRegistry 的基本实现 , 提供了默认编辑器和自定义编辑器的管理 ,只要担任 BeanWrapperImpl 的基类。
-
有几个成员变量
@Nullable private ConversionService conversionService; private boolean defaultEditorsActive = false; private boolean configValueEditorsActive = false; @Nullable private Map<Class<?>, PropertyEditor> defaultEditors; @Nullable private Map<Class<?>, PropertyEditor> overriddenDefaultEditors; @Nullable private Map<Class<?>, PropertyEditor> customEditors; @Nullable private Map<String, CustomEditorHolder> customEditorsForPath; @Nullable private Map<Class<?>, PropertyEditor> customEditorCache;
-
其中有 关于 ConversionService 的方法
-
/** * Specify a Spring 3.0 ConversionService to use for converting * property values, as an alternative to JavaBeans PropertyEditors. */ public void setConversionService(@Nullable ConversionService conversionService) { this.conversionService = conversionService; } /** * Return the associated ConversionService, if any. */ @Nullable public ConversionService getConversionService() { return this.conversionService; }
-
关于默认编辑器方法
//激活这个注册表实例的默认编辑器,允许懒注册的默认编辑器在需要的时候被注册 protected void registerDefaultEditors() { this.defaultEditorsActive = true; } //激活配置编辑器,为了配置值。这些编辑器没有被默认注册,因为他们不大适合用于数据绑定。 public void useConfigValueEditors() { this.configValueEditorsActive = true; } //重写默认编辑器 /* 和注册一个自定义编辑器不同,重写完之后还是一个默认编辑器 * 一个ConversionService会重写这样一个默认编辑器,然而,自定义编辑器通常重写ConversionService */ public void overrideDefaultEditor(Class<?> requiredType, PropertyEditor propertyEditor) { if (this.overriddenDefaultEditors == null) { this.overriddenDefaultEditors = new HashMap<>(); } this.overriddenDefaultEditors.put(requiredType, propertyEditor); } //根据属性类型得到默认属性编辑器,如果他们是active的,则懒注册他们 @Nullable public PropertyEditor getDefaultEditor(Class<?> requiredType) { if (!this.defaultEditorsActive) { return null; } if (this.overriddenDefaultEditors != null) { PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType); if (editor != null) { return editor; } } if (this.defaultEditors == null) { createDefaultEditors(); } return this.defaultEditors.get(requiredType); } //创建了许多默认编辑器(在这个注册表实例里) private void createDefaultEditors() { this.defaultEditors = new HashMap<>(64); // 简单的编辑器,没有参数化的功能 // 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(Path.class, new PathEditor()); this.defaultEditors.put(Pattern.class, new PatternEditor()); this.defaultEditors.put(Properties.class, new PropertiesEditor()); this.defaultEditors.put(Reader.class, new ReaderEditor()); 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()); this.defaultEditors.put(ZoneId.class, new ZoneIdEditor()); // 集合类的默认编辑器实例 // 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)); // 基本数组的默认编辑器 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); } } /** * 把这个注册表实例中的默认编辑器复制到另一个注册表中 * @param target the target registry to copy to */ protected void copyDefaultEditorsTo(PropertyEditorRegistrySupport target) { target.defaultEditorsActive = this.defaultEditorsActive; target.configValueEditorsActive = this.configValueEditorsActive; target.defaultEditors = this.defaultEditors; target.overriddenDefaultEditors = this.overriddenDefaultEditors; }
-
关于自定义编辑器的方法
- 实现的PropertyEditorRegistry接口中的三个方法
@Override public void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor) { registerCustomEditor(requiredType, null, propertyEditor); } @Override public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) { if (requiredType == null && propertyPath == null) { throw new IllegalArgumentException("Either requiredType or propertyPath is required"); } if (propertyPath != null) { if (this.customEditorsForPath == null) { this.customEditorsForPath = new LinkedHashMap<>(16); } this.customEditorsForPath.put(propertyPath, new CustomEditorHolder(propertyEditor, requiredType)); } else { if (this.customEditors == null) { this.customEditors = new LinkedHashMap<>(16); } this.customEditors.put(requiredType, propertyEditor); this.customEditorCache = null; } } @Override @Nullable public PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath) { Class<?> requiredTypeToUse = requiredType; if (propertyPath != null) { if (this.customEditorsForPath != null) { // Check property-specific editor first. PropertyEditor editor = getCustomEditor(propertyPath, requiredType); if (editor == null) { List<String> strippedPaths = new ArrayList<>(); addStrippedPropertyPaths(strippedPaths, "", propertyPath); for (Iterator<String> it = strippedPaths.iterator(); it.hasNext() && editor == null;) { String strippedPath = it.next(); editor = getCustomEditor(strippedPath, requiredType); } } if (editor != null) { return editor; } } if (requiredType == null) { requiredTypeToUse = getPropertyType(propertyPath); } } // No property-specific editor -> check type-specific editor. return getCustomEditor(requiredTypeToUse); } //这个注册表是否含有特定 array/Collection 元素类 的自定义编辑器 public boolean hasCustomEditorForElement(@Nullable Class<?> elementType, @Nullable String propertyPath) { if (propertyPath != null && this.customEditorsForPath != null) { for (Map.Entry<String, CustomEditorHolder> entry : this.customEditorsForPath.entrySet()) { if (PropertyAccessorUtils.matchesProperty(entry.getKey(), propertyPath) && entry.getValue().getPropertyEditor(elementType) != null) { return true; } } } // No property-specific editor -> check type-specific editor. return (elementType != null && this.customEditors != null && this.customEditors.containsKey(elementType)); } //根据property path得到该属性的类型,默认返回null,该方法在BeanWrapper中被再次定义,且在BeanWrapperImpl中被重写 @Nullable protected Class<?> getPropertyType(String propertyPath) { return null; } //返回指定类型和属性的自定义编辑器 @Nullable private PropertyEditor getCustomEditor(String propertyName, @Nullable Class<?> requiredType) { CustomEditorHolder holder = (this.customEditorsForPath != null ? this.customEditorsForPath.get(propertyName) : null); return (holder != null ? holder.getPropertyEditor(requiredType) : null); } //返回指定type的自定义编辑器,如果没有直接匹配的结果,将会尝试其父类的自定义编辑器(在任何情况下都能通过 getAsText将值呈现为String) @Nullable private PropertyEditor getCustomEditor(@Nullable Class<?> requiredType) { if (requiredType == null || this.customEditors == null) { return null; } // Check directly registered editor for type. PropertyEditor editor = this.customEditors.get(requiredType); if (editor == null) { // Check cached editor for type, registered for superclass or interface. if (this.customEditorCache != null) { editor = this.customEditorCache.get(requiredType); } if (editor == null) { // Find editor for superclass or interface. for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) { Class<?> key = it.next(); if (key.isAssignableFrom(requiredType)) { editor = this.customEditors.get(key); // Cache editor for search type, to avoid the overhead // of repeated assignable-from checks. if (this.customEditorCache == null) { this.customEditorCache = new HashMap<>(); } this.customEditorCache.put(requiredType, editor); } } } } return editor; } //猜猜该属性名称所对应的属性类型(从自定义编辑器中猜) @Nullable protected Class<?> guessPropertyTypeFromEditors(String propertyName) { if (this.customEditorsForPath != null) { CustomEditorHolder editorHolder = this.customEditorsForPath.get(propertyName); if (editorHolder == null) { List<String> strippedPaths = new ArrayList<>(); addStrippedPropertyPaths(strippedPaths, "", propertyName); for (Iterator<String> it = strippedPaths.iterator(); it.hasNext() && editorHolder == null;) { String strippedName = it.next(); editorHolder = this.customEditorsForPath.get(strippedName); } } if (editorHolder != null) { return editorHolder.getRegisteredType(); } } return null; } /**把这个注册表实例中的自定义编辑器复制到目标注册表实例中 */ protected void copyCustomEditorsTo(PropertyEditorRegistry target, @Nullable String nestedProperty) { String actualPropertyName = (nestedProperty != null ? PropertyAccessorUtils.getPropertyName(nestedProperty) : null); if (this.customEditors != null) { this.customEditors.forEach(target::registerCustomEditor); } if (this.customEditorsForPath != null) { this.customEditorsForPath.forEach((editorPath, editorHolder) -> { if (nestedProperty != null) { int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(editorPath); if (pos != -1) { String editorNestedProperty = editorPath.substring(0, pos); String editorNestedPath = editorPath.substring(pos + 1); if (editorNestedProperty.equals(nestedProperty) || editorNestedProperty.equals(actualPropertyName)) { target.registerCustomEditor( editorHolder.getRegisteredType(), editorNestedPath, editorHolder.getPropertyEditor()); } } } else { target.registerCustomEditor( editorHolder.getRegisteredType(), editorPath, editorHolder.getPropertyEditor()); } }); } } /**添加具有剥离键和/或索引的所有变体的属性路径。使用嵌套路径递归调用自身。*/ private void addStrippedPropertyPaths(List<String> strippedPaths, String nestedPath, String propertyPath) { int startIndex = propertyPath.indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR); if (startIndex != -1) { int endIndex = propertyPath.indexOf(PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR); if (endIndex != -1) { String prefix = propertyPath.substring(0, startIndex); String key = propertyPath.substring(startIndex, endIndex + 1); String suffix = propertyPath.substring(endIndex + 1, propertyPath.length()); // Strip the first key. strippedPaths.add(nestedPath + prefix + suffix); // Search for further keys to strip, with the first key stripped. addStrippedPropertyPaths(strippedPaths, nestedPath + prefix, suffix); // Search for further keys to strip, with the first key not stripped. addStrippedPropertyPaths(strippedPaths, nestedPath + prefix + key, suffix); } } }
-
内部类CustomEditorHolder
//具有属性名称的注册定制编辑器的持有人。 //保留PropertyEditor本身及其注册的类型。 private static final class CustomEditorHolder { private final PropertyEditor propertyEditor; @Nullable private final Class<?> registeredType; private CustomEditorHolder(PropertyEditor propertyEditor, @Nullable Class<?> registeredType) { this.propertyEditor = propertyEditor; this.registeredType = registeredType; } private PropertyEditor getPropertyEditor() { return this.propertyEditor; } @Nullable private Class<?> getRegisteredType() { return this.registeredType; } @Nullable private PropertyEditor getPropertyEditor(@Nullable Class<?> requiredType) { // 特殊情况:如果没有指定的requiredType(通常只发生在是Collection元素的时候),或者requiredType没有被分派到注册表中的类型(通常只发生在Object的通用属性的情况),那么就会返回PropertyEditor(没有注册为Collection和array type) if (this.registeredType == null || (requiredType != null && (ClassUtils.isAssignable(this.registeredType, requiredType) || ClassUtils.isAssignable(requiredType, this.registeredType))) || (requiredType == null && (!Collection.class.isAssignableFrom(this.registeredType) && !this.registeredType.isArray()))) { return this.propertyEditor; } else { return null; } } }
-
来源:https://www.cnblogs.com/woshi123/p/12658357.html