Bean copy 解决 java17 反射问题

This commit is contained in:
卢春梦 2025-02-13 10:36:29 +08:00
parent 3e7155a748
commit 0510f27902

View File

@ -21,6 +21,7 @@ import org.springframework.asm.Type;
import org.springframework.cglib.core.*; import org.springframework.cglib.core.*;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.HashMap; import java.util.HashMap;
@ -37,9 +38,10 @@ import java.util.Map;
* @author L.cm * @author L.cm
*/ */
public abstract class BaseBeanCopier { public abstract class BaseBeanCopier {
private static final String BEAN_NAME_PREFIX = BaseBeanCopier.class.getName();
private static final BeanCopierKey KEY_FACTORY = (BeanCopierKey) KeyFactory.create(BeanCopierKey.class); private static final BeanCopierKey KEY_FACTORY = (BeanCopierKey) KeyFactory.create(BeanCopierKey.class);
private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter"); private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter");
private static final Type BEAN_COPIER = TypeUtils.parseType(BaseBeanCopier.class.getName()); private static final Type BEAN_COPIER = TypeUtils.parseType(BEAN_NAME_PREFIX);
private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER}); private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER});
private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)"); private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)");
@ -59,11 +61,12 @@ public abstract class BaseBeanCopier {
} }
public static BaseBeanCopier create(Class source, Class target, ClassLoader classLoader, boolean useConverter) { public static BaseBeanCopier create(Class source, Class target, ClassLoader classLoader, boolean useConverter) {
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
Generator gen; Generator gen;
if (classLoader == null) { if (classLoader == null) {
gen = new Generator(); gen = new Generator(key);
} else { } else {
gen = new Generator(classLoader); gen = new Generator(key, classLoader);
} }
gen.setSource(source); gen.setSource(source);
gen.setTarget(target); gen.setTarget(target);
@ -80,19 +83,23 @@ public abstract class BaseBeanCopier {
abstract public void copy(Object from, Object to, Converter converter); abstract public void copy(Object from, Object to, Converter converter);
public static class Generator extends AbstractClassGenerator { public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(BaseBeanCopier.class.getName()); private static final Source SOURCE = new Source(BEAN_NAME_PREFIX);
private final Object key;
private final ClassLoader classLoader; private final ClassLoader classLoader;
private Class source; private Class source;
private Class target; private Class target;
private boolean useConverter; private boolean useConverter;
private String className;
Generator() { Generator(Object key) {
super(SOURCE); super(SOURCE);
this.key = key;
this.classLoader = null; this.classLoader = null;
} }
Generator(ClassLoader classLoader) { Generator(Object key, ClassLoader classLoader) {
super(SOURCE); super(SOURCE);
this.key = key;
this.classLoader = classLoader; this.classLoader = classLoader;
} }
@ -107,7 +114,6 @@ public abstract class BaseBeanCopier {
if (!Modifier.isPublic(target.getModifiers())) { if (!Modifier.isPublic(target.getModifiers())) {
setNamePrefix(target.getName()); setNamePrefix(target.getName());
} }
this.target = target; this.target = target;
} }
@ -126,7 +132,6 @@ public abstract class BaseBeanCopier {
} }
public BaseBeanCopier create() { public BaseBeanCopier create() {
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
return (BaseBeanCopier) super.create(key); return (BaseBeanCopier) super.create(key);
} }
@ -137,7 +142,7 @@ public abstract class BaseBeanCopier {
ClassEmitter ce = new ClassEmitter(v); ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2, ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC, Constants.ACC_PUBLIC,
getClassName(), getGenerateClassName(),
BEAN_COPIER, BEAN_COPIER,
null, null,
Constants.SOURCE_FILE); Constants.SOURCE_FILE);
@ -207,5 +212,28 @@ public abstract class BaseBeanCopier {
protected Object nextInstance(Object instance) { protected Object nextInstance(Object instance) {
return instance; return instance;
} }
@Override
protected Class generate(ClassLoaderData data) {
// 生成类名
data.reserveName(generateClassName(data.getUniqueNamePredicate()));
try {
return MethodHandles.lookup()
.defineClass(DefaultGeneratorStrategy.INSTANCE.generate(this))
.asSubclass(BaseBeanCopier.class);
} catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}
private String generateClassName(Predicate nameTestPredicate) {
this.className = DefaultNamingPolicy.INSTANCE.getClassName(BEAN_NAME_PREFIX, BEAN_NAME_PREFIX, key, nameTestPredicate);
return this.className;
}
private String getGenerateClassName() {
return className;
}
} }
} }