diff --git a/blade-core-tool/src/main/java/org/springblade/core/tool/support/BaseBeanCopier.java b/blade-core-tool/src/main/java/org/springblade/core/tool/support/BaseBeanCopier.java index f7a5a72..aa82f72 100644 --- a/blade-core-tool/src/main/java/org/springblade/core/tool/support/BaseBeanCopier.java +++ b/blade-core-tool/src/main/java/org/springblade/core/tool/support/BaseBeanCopier.java @@ -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; + } + } }