org.macrocloud.kernel.toolkit.convert.BaseConverter Maven / Gradle / Ivy
package org.macrocloud.kernel.toolkit.convert;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.macrocloud.kernel.toolkit.function.CheckedFunction;
import org.macrocloud.kernel.toolkit.utils.ClassUtil;
import org.macrocloud.kernel.toolkit.utils.ConvertUtil;
import org.macrocloud.kernel.toolkit.utils.ReflectUtil;
import org.macrocloud.kernel.toolkit.utils.Unchecked;
import org.springframework.cglib.core.Converter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 组合 spring cglib Converter 和 spring ConversionService.
*
* @author macro
*/
/** The Constant log. */
/** The Constant log. */
@Slf4j
/**
* Instantiates a new base converter.
*
* @param sourceClazz the source clazz
* @param targetClazz the target clazz
*/
@AllArgsConstructor
public class BaseConverter implements Converter {
/** The Constant TYPE_CACHE. */
private static final ConcurrentMap TYPE_CACHE = new ConcurrentHashMap<>();
/** The source clazz. */
private final Class> sourceClazz;
/** The target clazz. */
private final Class> targetClazz;
/**
* cglib convert.
*
* @param value 源对象属性
* @param target 目标对象属性类
* @param fieldName 目标的field名,原为 set 方法名,BladeBeanCopier 里做了更改
* @return {Object}
*/
@Override
@Nullable
public Object convert(Object value, Class target, final Object fieldName) {
if (value == null) {
return null;
}
// 类型一样,不需要转换
if (ClassUtil.isAssignableValue(target, value)) {
return value;
}
try {
TypeDescriptor targetDescriptor = BaseConverter.getTypeDescriptor(targetClazz, (String) fieldName);
// 1. 判断 sourceClazz 为 Map
if (Map.class.isAssignableFrom(sourceClazz)) {
return ConvertUtil.convert(value, targetDescriptor);
} else {
TypeDescriptor sourceDescriptor = BaseConverter.getTypeDescriptor(sourceClazz, (String) fieldName);
return ConvertUtil.convert(value, sourceDescriptor, targetDescriptor);
}
} catch (Throwable e) {
log.warn("BladeConverter error", e);
return null;
}
}
/**
* Gets the type descriptor.
*
* @param clazz the clazz
* @param fieldName the field name
* @return the type descriptor
*/
private static TypeDescriptor getTypeDescriptor(final Class> clazz, final String fieldName) {
String srcCacheKey = clazz.getName() + fieldName;
// 忽略抛出异常的函数,定义完整泛型,避免编译问题
CheckedFunction uncheckedFunction = (key) -> {
// 这里 property 理论上不会为 null
Field field = ReflectUtil.getField(clazz, fieldName);
if (field == null) {
throw new NoSuchFieldException(fieldName);
}
return new TypeDescriptor(field);
};
return TYPE_CACHE.computeIfAbsent(srcCacheKey, Unchecked.function(uncheckedFunction));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy