# Spring的PropertyEditor

## Spring中的属性编辑器PropertyEditor

![](/files/-LPKvkFHvfILmBEeS-OO)

**PropertyEditor**

一个Bean可能有很多属性需要设置，而配置时，我们只是写的字符串，Spring需要将字符串转换为我们定义的类型，比如：

```java
public class Person{
    private String name;
    private int age;

    //省略getter/setter
}
```

```markup
<bean id="person" class="com.maxwell.learning.spring.Person">
    <property name="name" value="maxwell" />
    <property name="age" value="20" />
</bean>
```

属性编辑器PropertyEditor工作就是：**将字符串转换为任意的Java类型**（如基本数据类型，我们写的Class，以及它们组成的Collection和Map等）。

PropertyEditor和PropertyEditorSupport都是java.bean中定义的接口/类，Spring则针对不同的情况进行了实现。

![](/files/-LPKvkFK3mz8wAQ5H2xj)

**PropertyEditorRegister**

管理PropertyEditor，定义属性编辑器PropertyEditor的注册和查找：`void registerCustomEditor`和`PropertyEditor findCustomEditor`。

�**PropertyEditorRegisterSupport**

PropertyEditorRegister的默认实现。

既然是Register，内部肯定也是使用Map来实现：Map\<Class\<?>, PropertyEditor> customEditors。

除此之外，内部还持有一个`ConversionService conversionService`对象。

**TypeConverter**

PropertyEditor负责将字符串转换为任意Java类型，但有时候并不一定拿字符串去转换，有可能是其他类型，TypeConverter就是负责进行类型转换的，可以看做是PropertyEditor的升级版：PropertyEditor(String -> anyType)，TypeConverter(anyType->anyType)。

**TypeConverterSupport**

对�TypeConverter的默认实现，其采用代理模式，交由TypeConverterDelegate实现，TypeConverterDelegate内部持有PropertyEditorRegisterSupport，转换策略为：先使用PropertyEditor转换器器转换，如果没找到对应的转换器器，会⽤ConversionService来进⾏行行对象转换。

**PropertyAccessor**

即前面获取到了某个字段的值，PropertyAccessor负责将这些具体的值设置到Bean的属性上或者说设置到对象的字段上，主要方法：

```java
//获取属性值
Object getPropertyValue(String propertyName)；
//设置属性值
void setPropertyValue(String propertyName, Object value)；
```

AbstractPropertyAccessor是它的实现类，AbstractNestablePropertyAccessor则支持嵌套结构的属性设置。

此外，Spring还使用PropertyValue来对\<propertyName, PropertyValue>进行了包装，即PropertyAccessor中还有类似如下的定义：

```java
void setPropertyValue(PropertyValue pv)
```

**BeanWrapper**

BeanWrapper继承自ConfigurablePropertyAccessor，相当于Bean属性操作的总接口，包含了属性编辑、类型转换，属性设置的全部功能，并额外定义了获取包装对象的方法：

```java
//Return the bean instance wrapped by this object.
Object getWrappedInstance();

//Return the type of the wrapped bean instance.
Class<?> getWrappedClass();

//Obtain the PropertyDescriptors for the wrapped object
PropertyDescriptor[] getPropertyDescriptors();
```

**BeanWrapperImpl**

BeanWrapper的默认实现，通常是由PropertyAccessorFactory工厂来创建BeanWrapperImpl的实例：

```java
�public abstract class PropertyAccessorFactory {

    public static BeanWrapper forBeanPropertyAccess(Object target) {
        return new BeanWrapperImpl(target);
    }

    public static ConfigurablePropertyAccessor forDirectFieldAccess(Object target) {
        return new DirectFieldAccessor(target);
    }
}
```

Spring中的ConversionService

�

## 参考

[spring笔记-PropertyAccessor](https://www.jianshu.com/p/c2c419cb5bea)

[Spring3.1.0实现原理分析(四).属性访问器(PropertyAccessor)](https://blog.csdn.net/roberts939299/article/details/70599506)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://maxwell.gitbook.io/way-to-architect/kuang-jia-huo-gong-ju/spring/springji-chu/springshi-xian-zhong-de-zhu-yao-lei/springde-property.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
