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 java.beans.PropertyDescriptor;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.HashMap;
@ -37,9 +38,10 @@ import java.util.Map;
* @author L.cm
*/
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 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 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) {
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
Generator gen;
if (classLoader == null) {
gen = new Generator();
gen = new Generator(key);
} else {
gen = new Generator(classLoader);
gen = new Generator(key, classLoader);
}
gen.setSource(source);
gen.setTarget(target);
@ -80,19 +83,23 @@ public abstract class BaseBeanCopier {
abstract public void copy(Object from, Object to, Converter converter);
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 Class source;
private Class target;
private boolean useConverter;
private String className;
Generator() {
Generator(Object key) {
super(SOURCE);
this.key = key;
this.classLoader = null;
}
Generator(ClassLoader classLoader) {
Generator(Object key, ClassLoader classLoader) {
super(SOURCE);
this.key = key;
this.classLoader = classLoader;
}
@ -107,7 +114,6 @@ public abstract class BaseBeanCopier {
if (!Modifier.isPublic(target.getModifiers())) {
setNamePrefix(target.getName());
}
this.target = target;
}
@ -126,7 +132,6 @@ public abstract class BaseBeanCopier {
}
public BaseBeanCopier create() {
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
return (BaseBeanCopier) super.create(key);
}
@ -137,7 +142,7 @@ public abstract class BaseBeanCopier {
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
getGenerateClassName(),
BEAN_COPIER,
null,
Constants.SOURCE_FILE);
@ -207,5 +212,28 @@ public abstract class BaseBeanCopier {
protected Object nextInstance(Object 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;
}
}
}