> For the complete documentation index, see [llms.txt](https://ankang.gitbook.io/commons/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ankang.gitbook.io/commons/commons-beans/ru-men/gai-nian.md).

# 概念

## BeanUtils

核心工具，提供实体拷贝的相关方法，支持属性映射、类型转换和批量拷贝等功能。

{% hint style="info" %}
拷贝过程可能抛出`BeanPropertyCopyException`
{% endhint %}

### BeanUtils.ConcurrencyManager

提供开启和关闭多线程处理模式和获取当前处理模式的方法：

{% hint style="info" %}

* public static boolean isMultiThreadProcessing()：获取当前处理模式
* public static void setMultiThreadProcessing(boolean value)：设置处理模式
  {% endhint %}

## BeanPropertyCopyException

属性拷贝过程中发生的异常。

{% hint style="info" %}
属性说明：

* propertyName：发生异常的属性名
* sourceObject：源对象
  {% endhint %}

## @Mapping

核心注解，配置字段的映射关系、转换器等内容。

{% hint style="info" %}
属性说明：

* targetClass：映射目标类类型，用于指定此注解的作用目标，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#mu-biao-lei-pei-zhi-shuo-ming)
* targetClassName：映射目标类全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* field：映射的字段名，支持嵌套的属性，默认为该字段名。
* ignore：是否忽略该字段，默认为`false`。
* oneway：是否为单向绑定，配置为`true`时，配置只在其他对象拷贝到本对象时生效，默认为`false`。
* datePattern：日期格式，字符串和日期字段映射时需要配置。
* converter：转换器的类型，在其他对象拷贝到本对象时生效，可以配置多个转换器。
* converterClassName：转换器类的全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* inverseConverter：反向转换器的类型，在本对象拷贝到其他对象时生效，可以配置多个转换器。
* inverseConverterClassName：反向转换器类的全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
  {% endhint %}

## @Nested

标记字段为嵌套的对象，需要指定嵌套对象以及对应映射对象的类型。

{% hint style="info" %}
属性说明：

* targetClass：映射目标类类型，用于指定此注解的作用目标，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#mu-biao-lei-pei-zhi-shuo-ming)
* targetClassName：映射目标类全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* thisClass：本字段的类型，作用于集合时，应为集合中元素的类型
* thisClassName：本字段类的全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* thatClass：映射字段的类型，作用于集合时，应为集合中元素的类型
* thatClassName：映射字段类的全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
  {% endhint %}

## @DictMapping

字典类映射使用的注解，用于代替原有的`AbstractDictionaryConverter`的方案。

{% hint style="info" %}
属性说明：

* targetClass：映射目标类类型，用于指定此注解的作用目标，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#mu-biao-lei-pei-zhi-shuo-ming)
* targetClassName：映射目标类全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* key：数据处理类参数（字典分类或者其他）
* resolver：数据处理类类型
* resolverClassName：数据处理类全路径名，详见[配置说明](/commons/commons-beans/ru-men/gai-nian/pei-zhi-shuo-ming.md#lei-class-lei-xing-de-shu-xing-pei-zhi-shuo-ming)
* mode：数据加载模式（批量/单条），默认为`FetchMode.BATCH`（批量）
* cacheable：是否启用数据缓存，默认为`true`
* async：是否异步更新缓存数据（加载仍然为同步），默认为`true`
* ttl：缓存的存活时间（秒），正整数，默认为`60`
  * 如果`async=true`：&#x20;
    * 缓存写入超过`ttl`则标记为待刷新（下次拷贝时使用旧数据，并异步加载新的字典数据）&#x20;
    * 缓存写入超过`ttl`两倍则标记为已过期（下次拷贝时需要先同步加载字典数据）
  * &#x20;如果`async=false`：
    * 缓存写入超过`ttl`则标记为已过期（下次拷贝时需要先同步加载字典数据）
* bidirectional：是否是双向查找（双向查找提供从value查找key的能力，如果key和value可能重复则建议配置为false），默认为true
  {% endhint %}

{% hint style="info" %}
数据加载模式（`DictMapping.FetchMode`）：

* SINGLE: 单条，根据源值直接查找映射结果，业务映射（如用户→部门）可采用此模式
* BATCH: 批量（默认），加载所有映射数据然后从中查找结果，字典表数据建议采用此模式

两种模式的对比：

* **时效性：**&#x6279;量模式所有数据缓存生命周期相同；单条模式每条数据有独立的生命周期。
* **一致性：**&#x5728;默认的批量模式下，如果映射数据有新增，则必须等待缓存失效之后才能加载新增数据（在此期间新增的数据映射结果均为`null`）；单条模式下，如果映射数据有新增，缓存中查找不到结果会触发一次接口调用获取新的映射数据。
* **性能：**&#x6279;量模式一次加载所有数据，因此一般来说性能优于单条模式；但是在存在热点数据的场景下（个别数据访问频率明显高于其他同类数据），单条模式效率更高（传输量小）。

需要配合`DictDataResolver`的实现类使用，参见下面的`DictDataResolver`接口说明。
{% endhint %}

## DictDataResolver

字典表数据加载适配器，一般来说依赖于某个服务，负责获取数据并转换为字典数据。

1. 当`@DictMapping`配置`mode=FetchMode.BATCH`时，使用`Map resolve(String key);`方法，参数是`@DictMapping`中配置的`key`属性，返回字典映射所有数据的`Map<Object, Object>`。
2. 当`@DictMapping`配置`mode=FetchMode.SINGLE`时，使用`Object resolveSingle(String key, Object source);`方法，参数是`@DictMapping`中配置的`key`属性以及映射源属性的值，返回映射结果。

{% hint style="info" %}
`resolveSingle`方法提供默认实现：调用`resolve`方法获取所有字典信息，然后遍历获取映射结果。如果`@DictMapping(mode=FetchMode.SINGLE)`，建议覆盖默认的实现以优化性能。
{% endhint %}

## TypeConverter

类型转换器接口，自定义的转换器需要实现此接口。使用者需要自行处理空值和异常（统一捕获异常并转换为`TypeConvertException`）。

## AbstractTypeConverter

类型转换器的抽象类，封装了空值判断和异常处理逻辑。默认对于空值会直接返回，使用者如果对空值有特殊的转换需求，可以覆盖`convertNull()`方法返回期望的值。

## AbstractToStringConverter

对象/集合转换为单个字符串的转换器抽象类，作用于集合时，转换器会将每个元素的处理结果用`getDelimiter()`方法返回的分隔符分隔（默认分隔符为","）。

使用者需要实现`itemToString(Object item)`方法，实现对象/集合元素转换为字符串的逻辑。可以根据需要重写`getDelimiter()`方法。

## AbstractListConverter

集合转换为`List`的转换器抽象类，针对一个给定的集合，遍历其中的元素进行转换，然后返回一个目标对象的`List`（使用`ArrayList`实现）。

使用者需要实现`convertItem(Object item)`方法，实现集合中单个元素的转换逻辑。

## AbstractSetConverter

集合转换为`Set`的转换器抽象类，针对一个给定的集合，遍历其中的元素进行转换，然后返回一个目标对象的`Set`（使用`HashSet`实现）。

使用者需要实现`convertItem(Object item)`方法，实现集合中单个元素的转换逻辑。

## ~~AbstractDictionaryConverter~~

字典表数据的转换器抽象类，提供字典类数据的双向转换功能。

使用者需要实现`getDictionary()`方法，返回`Map<Object, Object>`类型的字典数据。

{% hint style="info" %}
从1.7.0版本开始标记为`@Deprecated`，字典映射请使用`@DictMapping`和`DictDataResolver`
{% endhint %}
