优化Reproduce

This commit is contained in:
redkale
2023-08-04 15:38:01 +08:00
parent 25a7aeacfa
commit 0fb3684a18
2 changed files with 168 additions and 0 deletions

View File

@@ -6,6 +6,7 @@
package org.redkale.util;
import java.lang.reflect.*;
import java.util.concurrent.ConcurrentHashMap;
import org.redkale.asm.*;
import static org.redkale.asm.Opcodes.*;
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 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) {
java.lang.reflect.Method method = null;
try {
@@ -44,6 +55,12 @@ public interface Invoker<OBJECT_TYPE, RETURN_TYPE> {
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) {
RedkaleClassLoader.putReflectionDeclaredMethods(clazz.getName());
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();
}
}

View File

@@ -20,9 +20,27 @@ import static org.redkale.asm.Opcodes.*;
*/
public interface Reproduce<D, S> extends BiFunction<D, S, D> {
/**
* 将源对象字段复制到目标对象
*
* @param dest 目标对象
* @param src 源对象
*
* @return 目标对象
*/
@Override
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) {
if (src == null || dest == 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);
}
/**
* 将源对象字段复制到目标对象
*
* @param <D> 目标类泛型
* @param <S> 源类泛型
* @param destClass 目标类名
* @param src 源对象
*
* @return 目标对象
*/
public static <D, S> D copy(final Class<D> destClass, final S src) {
if (src == 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);
}
/**
* 创建源类到目标类的复制器并缓存
*
* @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) {
if (destClass == srcClass) {
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) {
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) {
return create(destClass, srcClass, (BiPredicate) null, names);
}
/**
* 创建源类到目标类的复制器
*
* @param <D> 目标类泛型
* @param <S> 源类泛型
* @param destClass 目标类名
* @param srcClass 源类名
* @param srcColumnPredicate 需复制的字段名判断期
*
* @return 复制器
*/
@SuppressWarnings("unchecked")
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);
}
/**
* 创建源类到目标类的复制器
*
* @param <D> 目标类泛型
* @param <S> 源类泛型
* @param destClass 目标类名
* @param srcClass 源类名
* @param srcColumnPredicate 需复制的字段名判断期
* @param names 源字段名与目标字段名的映射关系
*
* @return 复制器
*/
@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) {
return create(destClass, srcClass, (sc, m) -> srcColumnPredicate.test(m), names);
}
/**
* 创建源类到目标类的复制器
*
* @param <D> 目标类泛型
* @param <S> 源类泛型
* @param destClass 目标类名
* @param srcClass 源类名
* @param srcColumnPredicate 需复制的字段名判断期
*
* @return 复制器
*/
@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) {
return create(destClass, srcClass, srcColumnPredicate, (Map<String, String>) null);
}
/**
* 创建源类到目标类的复制器
*
* @param <D> 目标类泛型
* @param <S> 源类泛型
* @param destClass 目标类名
* @param srcClass 源类名
* @param srcColumnPredicate 需复制的字段名判断期
* @param names 源字段名与目标字段名的映射关系
*
* @return 复制器
*/
@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) {
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 destClassName = destClass.getName().replace('.', '/');