Skip to content

Commit

Permalink
✨ mica-core 解决 bean copy java17 反射报错
Browse files Browse the repository at this point in the history
  • Loading branch information
li-xunhuan committed Feb 13, 2025
1 parent 4114a74 commit 4c2250e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
import java.util.HashMap;
Expand All @@ -47,15 +48,15 @@
* @author L.cm
*/
public abstract class MicaBeanCopier {
private static final String BEAN_NAME_PREFIX = MicaBeanCopier.class.getName();
private static final Type CONVERTER = TypeUtils.parseType(Converter.class.getName());
private static final Type BEAN_COPIER = TypeUtils.parseType(MicaBeanCopier.class.getName());
private static final Type BEAN_COPIER = TypeUtils.parseType(BEAN_NAME_PREFIX);
private static final Type BEAN_MAP = TypeUtils.parseType(Map.class.getName());
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 BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object)");
private static final Type CLASS_UTILS = TypeUtils.parseType(ClassUtils.class.getName());
private static final Signature IS_ASSIGNABLE_VALUE = TypeUtils.parseSignature("boolean isAssignableValue(Class, Object)");
private static final String BEAN_NAME_PREFIX = MicaBeanCopier.class.getName();
/**
* The map to store {@link MicaBeanCopier} of source type and class type for copy.
*/
Expand All @@ -69,15 +70,11 @@ public static MicaBeanCopier create(Class source, Class target, boolean useConve
MicaBeanCopierKey copierKey = new MicaBeanCopierKey(source, target, useConverter, nonNull);
// 利用 ConcurrentMap 缓存 提高性能,接近 直接 get set
return CollectionUtil.computeIfAbsent(BEAN_COPIER_MAP, copierKey, key -> {
Generator gen = new Generator();
gen.setSource(key.source());
gen.setTarget(key.target());
Generator gen = new Generator(key);
gen.setContextClass(MicaBeanCopier.class);
gen.setUseConverter(key.useConverter());
gen.setNonNull(key.nonNull());
gen.setNamePrefix(BEAN_NAME_PREFIX);
gen.setUseCache(true);
return gen.create(key);
return gen.create();
});
}

Expand All @@ -91,37 +88,28 @@ public static MicaBeanCopier create(Class source, Class target, boolean useConve
public abstract void copy(Object from, Object to, @Nullable Converter converter);

public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(MicaBeanCopier.class.getName());
private Class source;
private Class target;
private boolean useConverter;
private boolean nonNull;

Generator() {
private static final Source SOURCE = new Source(BEAN_NAME_PREFIX);
private final MicaBeanCopierKey copierKey;
private final Class source;
private final Class target;
private final boolean useConverter;
private final boolean nonNull;
private String className;

Generator(MicaBeanCopierKey copierKey) {
super(SOURCE);
}

public void setSource(Class source) {
this.source = source;
}

public void setTarget(Class target) {
this.target = target;
this.copierKey = copierKey;
this.source = copierKey.source();
this.target = copierKey.target();
this.useConverter = copierKey.useConverter();
this.nonNull = copierKey.nonNull();
}

@Override
public void setNamePrefix(String namePrefix) {
super.setNamePrefix(namePrefix);
}

public void setUseConverter(boolean useConverter) {
this.useConverter = useConverter;
}

public void setNonNull(boolean nonNull) {
this.nonNull = nonNull;
}

@Override
protected ClassLoader getDefaultClassLoader() {
// L.cm 保证 和 返回使用同一个 ClassLoader
Expand All @@ -133,9 +121,8 @@ protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(source);
}

@Override
public MicaBeanCopier create(Object key) {
return (MicaBeanCopier) super.create(key);
public MicaBeanCopier create() {
return (MicaBeanCopier) super.create(copierKey);
}

@Override
Expand All @@ -145,7 +132,7 @@ public void generateClass(ClassVisitor v) {
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Opcodes.V1_2,
Opcodes.ACC_PUBLIC,
getClassName(),
this.className,
BEAN_COPIER,
null,
Constants.SOURCE_FILE);
Expand Down Expand Up @@ -302,6 +289,25 @@ protected Object nextInstance(Object instance) {
return instance;
}

@Override
protected Class generate(ClassLoaderData data) {
// 生成类名
this.className = generateClassName(data);
try {
return MethodHandles.lookup()
.defineClass(DefaultGeneratorStrategy.INSTANCE.generate(this))
.asSubclass(MicaBeanCopier.class);
} catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}

private String generateClassName(ClassLoaderData data) {
String name = DefaultNamingPolicy.INSTANCE.getClassName(BEAN_NAME_PREFIX, BEAN_NAME_PREFIX, copierKey, data.getUniqueNamePredicate());
data.reserveName(name);
return name;
}

/**
* 处理 map 的 copy
* @param ce ClassEmitter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static MicaBeanMap create(Object bean) {
public abstract MicaBeanMap newInstance(Object o);

public static class MicaGenerator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(MicaBeanMap.class.getName());
private static final Source SOURCE = new Source(BEAN_NAME_PREFIX);

private Object bean;
private Class beanClass;
Expand Down

0 comments on commit 4c2250e

Please sign in to comment.