优化Reproduce
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
package org.redkale.util;
|
package org.redkale.util;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.redkale.asm.*;
|
import org.redkale.asm.*;
|
||||||
import static org.redkale.asm.Opcodes.*;
|
import static org.redkale.asm.Opcodes.*;
|
||||||
import org.redkale.asm.Type;
|
import org.redkale.asm.Type;
|
||||||
@@ -34,6 +35,16 @@ public interface Invoker<OBJECT_TYPE, RETURN_TYPE> {
|
|||||||
*/
|
*/
|
||||||
public RETURN_TYPE invoke(OBJECT_TYPE obj, Object... params);
|
public RETURN_TYPE invoke(OBJECT_TYPE obj, Object... params);
|
||||||
|
|
||||||
|
public static <OBJECT_TYPE, RETURN_TYPE> Invoker<OBJECT_TYPE, RETURN_TYPE> load(final Class<OBJECT_TYPE> clazz, final String methodName, final Class... paramTypes) {
|
||||||
|
java.lang.reflect.Method method = null;
|
||||||
|
try {
|
||||||
|
method = clazz.getMethod(methodName, paramTypes);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RedkaleException(ex);
|
||||||
|
}
|
||||||
|
return load(clazz, method);
|
||||||
|
}
|
||||||
|
|
||||||
public static <OBJECT_TYPE, RETURN_TYPE> Invoker<OBJECT_TYPE, RETURN_TYPE> create(final Class<OBJECT_TYPE> clazz, final String methodName, final Class... paramTypes) {
|
public static <OBJECT_TYPE, RETURN_TYPE> Invoker<OBJECT_TYPE, RETURN_TYPE> create(final Class<OBJECT_TYPE> clazz, final String methodName, final Class... paramTypes) {
|
||||||
java.lang.reflect.Method method = null;
|
java.lang.reflect.Method method = null;
|
||||||
try {
|
try {
|
||||||
@@ -44,6 +55,12 @@ public interface Invoker<OBJECT_TYPE, RETURN_TYPE> {
|
|||||||
return create(clazz, method);
|
return create(clazz, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <C, T> Invoker<C, T> load(final Class<C> clazz, final Method method) {
|
||||||
|
return InvokerInner.caches
|
||||||
|
.computeIfAbsent(clazz, t -> new ConcurrentHashMap<>())
|
||||||
|
.computeIfAbsent(method, v -> create(clazz, method));
|
||||||
|
}
|
||||||
|
|
||||||
public static <C, T> Invoker<C, T> create(final Class<C> clazz, final Method method) {
|
public static <C, T> Invoker<C, T> create(final Class<C> clazz, final Method method) {
|
||||||
RedkaleClassLoader.putReflectionDeclaredMethods(clazz.getName());
|
RedkaleClassLoader.putReflectionDeclaredMethods(clazz.getName());
|
||||||
RedkaleClassLoader.putReflectionMethod(clazz.getName(), method);
|
RedkaleClassLoader.putReflectionMethod(clazz.getName(), method);
|
||||||
@@ -225,4 +242,9 @@ public interface Invoker<OBJECT_TYPE, RETURN_TYPE> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class InvokerInner {
|
||||||
|
|
||||||
|
static final ConcurrentHashMap<Class, ConcurrentHashMap<Method, Invoker>> caches = new ConcurrentHashMap();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,27 @@ import static org.redkale.asm.Opcodes.*;
|
|||||||
*/
|
*/
|
||||||
public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将源对象字段复制到目标对象
|
||||||
|
*
|
||||||
|
* @param dest 目标对象
|
||||||
|
* @param src 源对象
|
||||||
|
*
|
||||||
|
* @return 目标对象
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public D apply(D dest, S src);
|
public D apply(D dest, S src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将源对象字段复制到目标对象
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param dest 目标对象
|
||||||
|
* @param src 源对象
|
||||||
|
*
|
||||||
|
* @return 目标对象
|
||||||
|
*/
|
||||||
public static <D, S> D copy(final D dest, final S src) {
|
public static <D, S> D copy(final D dest, final S src) {
|
||||||
if (src == null || dest == null) {
|
if (src == null || dest == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -32,6 +50,16 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
|||||||
return load(destClass, (Class<S>) src.getClass()).apply(creator.create(), src);
|
return load(destClass, (Class<S>) src.getClass()).apply(creator.create(), src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将源对象字段复制到目标对象
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param src 源对象
|
||||||
|
*
|
||||||
|
* @return 目标对象
|
||||||
|
*/
|
||||||
public static <D, S> D copy(final Class<D> destClass, final S src) {
|
public static <D, S> D copy(final Class<D> destClass, final S src) {
|
||||||
if (src == null) {
|
if (src == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -40,6 +68,16 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
|||||||
return load(destClass, (Class<S>) src.getClass()).apply(creator.create(), src);
|
return load(destClass, (Class<S>) src.getClass()).apply(creator.create(), src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器并缓存
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
public static <D, S> Reproduce<D, S> load(final Class<D> destClass, final Class<S> srcClass) {
|
public static <D, S> Reproduce<D, S> load(final Class<D> destClass, final Class<S> srcClass) {
|
||||||
if (destClass == srcClass) {
|
if (destClass == srcClass) {
|
||||||
return ReproduceInner.reproduceOneCaches
|
return ReproduceInner.reproduceOneCaches
|
||||||
@@ -51,31 +89,139 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass) {
|
||||||
return create(destClass, srcClass, (BiPredicate) null, (Map<String, String>) null);
|
return create(destClass, srcClass, (BiPredicate) null, (Map<String, String>) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
* @param names 源字段名与目标字段名的映射关系
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Map<String, String> names) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Map<String, String> names) {
|
||||||
return create(destClass, srcClass, (BiPredicate) null, names);
|
return create(destClass, srcClass, (BiPredicate) null, names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
* @param srcColumnPredicate 需复制的字段名判断期
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Predicate<String> srcColumnPredicate) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Predicate<String> srcColumnPredicate) {
|
||||||
return create(destClass, srcClass, (sc, m) -> srcColumnPredicate.test(m), (Map<String, String>) null);
|
return create(destClass, srcClass, (sc, m) -> srcColumnPredicate.test(m), (Map<String, String>) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
* @param srcColumnPredicate 需复制的字段名判断期
|
||||||
|
* @param names 源字段名与目标字段名的映射关系
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Predicate<String> srcColumnPredicate, final Map<String, String> names) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Predicate<String> srcColumnPredicate, final Map<String, String> names) {
|
||||||
return create(destClass, srcClass, (sc, m) -> srcColumnPredicate.test(m), names);
|
return create(destClass, srcClass, (sc, m) -> srcColumnPredicate.test(m), names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
* @param srcColumnPredicate 需复制的字段名判断期
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final BiPredicate<java.lang.reflect.AccessibleObject, String> srcColumnPredicate) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final BiPredicate<java.lang.reflect.AccessibleObject, String> srcColumnPredicate) {
|
||||||
return create(destClass, srcClass, srcColumnPredicate, (Map<String, String>) null);
|
return create(destClass, srcClass, srcColumnPredicate, (Map<String, String>) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建源类到目标类的复制器
|
||||||
|
*
|
||||||
|
* @param <D> 目标类泛型
|
||||||
|
* @param <S> 源类泛型
|
||||||
|
* @param destClass 目标类名
|
||||||
|
* @param srcClass 源类名
|
||||||
|
* @param srcColumnPredicate 需复制的字段名判断期
|
||||||
|
* @param names 源字段名与目标字段名的映射关系
|
||||||
|
*
|
||||||
|
* @return 复制器
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final BiPredicate<java.lang.reflect.AccessibleObject, String> srcColumnPredicate, final Map<String, String> names) {
|
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final BiPredicate<java.lang.reflect.AccessibleObject, String> srcColumnPredicate, final Map<String, String> names) {
|
||||||
|
if (Map.class.isAssignableFrom(destClass) && Map.class.isAssignableFrom(srcClass)) {
|
||||||
|
final Map names0 = names;
|
||||||
|
if (srcColumnPredicate != null) {
|
||||||
|
if (names != null) {
|
||||||
|
return (D dest, S src) -> {
|
||||||
|
Map d = (Map) dest;
|
||||||
|
((Map) src).forEach((k, v) -> {
|
||||||
|
if (srcColumnPredicate.test(null, k.toString())) {
|
||||||
|
d.put(names0.getOrDefault(k, k), v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return (D dest, S src) -> {
|
||||||
|
Map d = (Map) dest;
|
||||||
|
((Map) src).forEach((k, v) -> {
|
||||||
|
if (srcColumnPredicate.test(null, k.toString())) {
|
||||||
|
d.put(k, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (names != null) {
|
||||||
|
return (D dest, S src) -> {
|
||||||
|
Map d = (Map) dest;
|
||||||
|
((Map) src).forEach((k, v) -> {
|
||||||
|
d.put(names0.getOrDefault(k, k), v);
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new Reproduce<D, S>() {
|
||||||
|
@Override
|
||||||
|
public D apply(D dest, S src) {
|
||||||
|
((Map) dest).putAll((Map) src);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
final String supDynName = Reproduce.class.getName().replace('.', '/');
|
final String supDynName = Reproduce.class.getName().replace('.', '/');
|
||||||
final String destClassName = destClass.getName().replace('.', '/');
|
final String destClassName = destClass.getName().replace('.', '/');
|
||||||
|
|||||||
Reference in New Issue
Block a user