add CglibUtil

This commit is contained in:
Looly 2020-08-22 22:06:16 +08:00
parent c8f911ad4b
commit b46d99a15a
6 changed files with 164 additions and 0 deletions

View File

@ -13,6 +13,7 @@
* 【core 】 Validator修改isCitizenId校验pr#1032@Github
* 【core 】 增加PathUtil和FileNameUtil分离FileUtil中部分方法
* 【core 】 改造IndexedComparator增加InstanceComparator
* 【extra 】 增加CglibUtil
### Bug修复#
* 【poi 】 修复ExcelBase.isXlsx方法判断问题issue#I1S502@Gitee

View File

@ -31,6 +31,7 @@
<emoji-java.version>5.1.1</emoji-java.version>
<servlet-api.version>4.0.1</servlet-api.version>
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
<cglib.version>3.3.0</cglib.version>
</properties>
<dependencies>
@ -232,6 +233,13 @@
<version>1.1.8</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@ -0,0 +1,34 @@
package cn.hutool.extra.cglib;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.util.StrUtil;
import net.sf.cglib.beans.BeanCopier;
import java.beans.PropertyDescriptor;
/**
* BeanCopier属性缓存<br>
* 缓存用于防止多次反射造成的性能问题
*
* @author Looly
* @since 5.4.1
*/
public enum BeanCopierCache {
INSTANCE;
private final SimpleCache<String, BeanCopier> cache = new SimpleCache<>();
/**
* 获得属性名和{@link PropertyDescriptor}Map映射
*
* @param srcClass 源Bean的类
* @param targetClass 目标Bean的类
* @param supplier 缓存对象产生函数
* @return 属性名和{@link PropertyDescriptor}Map映射
* @since 5.4.1
*/
public BeanCopier get(Class<?> srcClass, Class<?> targetClass, Func0<BeanCopier> supplier) {
return this.cache.get(StrUtil.format("{}_{}", srcClass.getName(), srcClass.getName()), supplier);
}
}

View File

@ -0,0 +1,83 @@
package cn.hutool.extra.cglib;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ReflectUtil;
import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.beans.BeanMap;
import net.sf.cglib.core.Converter;
/**
* Cglib工具类
*
* @author looly
* @since 5.4.1
*/
public class CglibUtil {
/**
* 拷贝Bean对象属性到目标类型<br>
* 此方法通过指定目标类型自动创建之然后拷贝属性
*
* @param <T> 目标对象类型
* @param source 源bean对象
* @param targetClass 目标bean类自动实例化此对象
*/
public static <T> T copy(Object source, Class<T> targetClass) {
return copy(source, targetClass, null);
}
/**
* 拷贝Bean对象属性<br>
* 此方法通过指定目标类型自动创建之然后拷贝属性
*
* @param <T> 目标对象类型
* @param source 源bean对象
* @param targetClass 目标bean类自动实例化此对象
* @param converter 转换器无需可传{@code null}
*/
public static <T> T copy(Object source, Class<T> targetClass, Converter converter) {
final T target = ReflectUtil.newInstanceIfPossible(targetClass);
copy(source, target);
return target;
}
/**
* 拷贝Bean对象属性
*
* @param source 源bean对象
* @param target 目标bean对象
*/
public static void copy(Object source, Object target) {
copy(source, target, null);
}
/**
* 拷贝Bean对象属性
*
* @param source 源bean对象
* @param target 目标bean对象
* @param converter 转换器无需可传{@code null}
*/
public static void copy(Object source, Object target, Converter converter) {
Assert.notNull(source, "Source bean must be not null.");
Assert.notNull(target, "Target bean must be not null.");
final Class<?> sourceClass = source.getClass();
final Class<?> targetClass = target.getClass();
final BeanCopier beanCopier = BeanCopierCache.INSTANCE.get(
sourceClass, targetClass,
() -> BeanCopier.create(sourceClass, targetClass, null != converter));
beanCopier.copy(source, target, converter);
}
/**
* 将Bean转换为Map
*
* @param bean Bean对象
* @return {@link BeanMap}
*/
public static BeanMap toMap(Object bean){
return BeanMap.create(bean);
}
}

View File

@ -0,0 +1,7 @@
/**
* Cglib库方法封装
*
* @author looly
*
*/
package cn.hutool.extra.cglib;

View File

@ -0,0 +1,31 @@
package cn.hutool.extra.cglib;
import lombok.Data;
import org.junit.Assert;
import org.junit.Test;
public class CglibUtilTest {
@Test
public void copyTest() {
SampleBean bean = new SampleBean();
bean.setValue("Hello world");
OtherSampleBean otherBean = new OtherSampleBean();
CglibUtil.copy(bean, otherBean);
Assert.assertEquals("Hello world", otherBean.getValue());
OtherSampleBean otherBean2 = CglibUtil.copy(bean, OtherSampleBean.class);
Assert.assertEquals("Hello world", otherBean2.getValue());
}
@Data
public static class SampleBean {
private String value;
}
@Data
public static class OtherSampleBean {
private String value;
}
}