工具类方法
public static <T> T newByCglib(Class<T> tClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(tClass);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
Object result = methodProxy.invokeSuper(o, objects);
return result;
});
Object o = enhancer.create();
return (T) o;
}
public static <T> T newByReflect(Class<T> tClass) {
if (null == tClass) {
return null;
}
T t = null;
try {
Constructor<T> declaredConstructor = tClass.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
t = declaredConstructor.newInstance();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return t;
}
public static <V> V copy(Object o) {
Class<?> oClass = o.getClass();
Type[] types = ((ParameterizedType) oClass.getGenericSuperclass()).getActualTypeArguments();
Class<V> vClass = null;
for (Type type : types) {
if (type != oClass) {
vClass = (Class<V>) type;
}
}
if (null == vClass) {
System.out.println("请添加目标类泛型泛型!");
return null;
}
BeanCopier beanCopier = BeanCopier.create(oClass, vClass, false);
V v = BeanUtil.newByCglib(vClass);
beanCopier.copy(o, v, null);
return v;
}
方法一
在BaseEntity<T,V>将泛型传进来,然后创建默认的转换方法(耦合高点,使用方便)
@Data
public class BaseEntity<T extends BaseEntity,V extends BaseVO> implements Serializable {
private static final long serialVersionUID = -2207728304131779727L;
/**
* 初始化插入数据.
*/
public T initInsert() {
this.setDeleted(SystemConstant.DELETED_F);
this.setCreateTime(new Date());
this.setUpdateTime(new Date());
return (T) this;
}
/**
* 初始化更新数据.
*/
public T initUpdate() {
this.setUpdateTime(new Date());
return (T) this;
}
/**
* 主键ID
*/
private String id;
/**
* 创建时间
*/
@ApiModelProperty(hidden = true)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
*/
@ApiModelProperty(hidden = true)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 是否已删除【0:未删除,1:已删除】
*/
@JsonIgnore
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
public V converterVO(){
Class<?> oClass = this.getClass();
Type[] types = ((ParameterizedType) oClass.getGenericSuperclass()).getActualTypeArguments();
Class<V> vClass = null;
//也可以指定目标类泛型的位置
for (Type type : types) {
if (type != oClass) {
vClass = (Class<V>) type;
}
}
if (null == vClass) {
System.out.println("请添加目标类泛型泛型!");
return null;
}
BeanCopier beanCopier = BeanCopier.create(oClass, vClass, false);
V v = BeanUtil.newByReflect(vClass);
beanCopier.copy(this, v, null);
return v;
}
}
方法二
使用java8 接口default方法(解耦合,多实现一个接口)
import com.alibaba.fastjson.JSON;
import org.springframework.cglib.beans.BeanCopier;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author zakza
*/
public interface BeanConverter<T> {
/**
* 将当前对象转换成泛型实例
*
* @return
*/
default T converter() {
Class<? extends BeanConverter> oClass = this.getClass();
Type[] types = oClass.getGenericInterfaces();
ParameterizedType parameterized = (ParameterizedType) types[0];
Class<T> tClass = (Class<T>) parameterized.getActualTypeArguments()[0];
T t = BeanUtil.newByReflect(tClass);
BeanCopier beanCopier = BeanCopier.create(oClass, tClass, false);
beanCopier.copy(this, t, null);
return t;
}
}
总结:
使用反射创建对象比cglib快,调用方法之类的cglib快,cglib创建的对象无法再次转换(或者是我没找到方法)
如果VO->DO->DTO创建对象不能用newByCglib方法,会报错,debug看到接口泛型对象是cglib proxy factory
反射创建对象, BeanCopier 复制属性,简单测试1000000次,2s