diff --git a/src/main/java/org/redkale/asm/AsmMethodBoost.java b/src/main/java/org/redkale/asm/AsmMethodBoost.java index 42efa246f..616658876 100644 --- a/src/main/java/org/redkale/asm/AsmMethodBoost.java +++ b/src/main/java/org/redkale/asm/AsmMethodBoost.java @@ -29,6 +29,7 @@ import static org.redkale.asm.Opcodes.LLOAD; import static org.redkale.asm.Opcodes.LRETURN; import static org.redkale.asm.Opcodes.RETURN; import org.redkale.inject.ResourceFactory; +import org.redkale.util.RedkaleClassLoader.DynBytesClassLoader; import org.redkale.util.Utility; /** @@ -100,7 +101,7 @@ public abstract class AsmMethodBoost { * @return 下一个新的方法名,不做任何处理应返回参数newMethodName */ public abstract AsmNewMethod doMethod( - ClassLoader classLoader, + DynBytesClassLoader classLoader, ClassWriter cw, Class serviceImplClass, String newDynName, @@ -117,7 +118,8 @@ public abstract class AsmMethodBoost { * @param newDynName 动态新类名 * @param fieldPrefix 动态字段的前缀 */ - public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {} + public void doAfterMethods( + DynBytesClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {} /** * 实例对象进行操作,通常用于给动态的字段赋值 @@ -126,7 +128,7 @@ public abstract class AsmMethodBoost { * @param resourceFactory ResourceFactory * @param service 实例对象 */ - public abstract void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, T service); + public abstract void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, T service); protected AsmMethodBean getMethodBean(Method method) { Map methodBeans = AsmMethodBoost.getMethodBeans(serviceType); @@ -306,7 +308,7 @@ public abstract class AsmMethodBoost { @Override public AsmNewMethod doMethod( - ClassLoader classLoader, + DynBytesClassLoader classLoader, ClassWriter cw, Class serviceImplClass, String newDynName, @@ -325,7 +327,8 @@ public abstract class AsmMethodBoost { } @Override - public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { + public void doAfterMethods( + DynBytesClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { for (AsmMethodBoost item : items) { if (item != null) { item.doAfterMethods(classLoader, cw, newDynName, fieldPrefix); @@ -334,7 +337,7 @@ public abstract class AsmMethodBoost { } @Override - public void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, T service) { + public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, T service) { for (AsmMethodBoost item : items) { if (item != null) { item.doInstance(classLoader, resourceFactory, service); diff --git a/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java b/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java index e6fdde67b..d2df1d39c 100644 --- a/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java +++ b/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java @@ -30,6 +30,7 @@ import org.redkale.cached.Cached; import org.redkale.inject.ResourceFactory; import org.redkale.service.LoadMode; import org.redkale.util.RedkaleClassLoader; +import org.redkale.util.RedkaleClassLoader.DynBytesClassLoader; import org.redkale.util.RedkaleException; import org.redkale.util.ThrowSupplier; import org.redkale.util.TypeToken; @@ -62,7 +63,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost { @Override public AsmNewMethod doMethod( - final ClassLoader classLoader, + final DynBytesClassLoader classLoader, final ClassWriter cw, final Class serviceImplClass, final String newDynName, @@ -215,7 +216,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost { } @Override - public void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, Object service) { + public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) { Class clazz = service.getClass(); if (actionMap == null) { // 为null表示没有调用过doMethod, 动态类在编译是已经生成好了 actionMap = new LinkedHashMap<>(); diff --git a/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java b/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java index 094a01eeb..9e46cac76 100644 --- a/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java +++ b/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java @@ -20,6 +20,7 @@ import org.redkale.asm.Type; import org.redkale.inject.ResourceFactory; import org.redkale.locked.Locked; import org.redkale.service.LoadMode; +import org.redkale.util.RedkaleClassLoader.DynBytesClassLoader; import org.redkale.util.RedkaleException; /** @author zhangjx */ @@ -38,7 +39,7 @@ public class LockedAsmMethodBoost extends AsmMethodBoost { @Override public AsmNewMethod doMethod( - ClassLoader classLoader, + DynBytesClassLoader classLoader, ClassWriter cw, Class serviceImplClass, String newDynName, @@ -90,12 +91,12 @@ public class LockedAsmMethodBoost extends AsmMethodBoost { } @Override - public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { + public void doAfterMethods(DynBytesClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { // do nothing } @Override - public void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, Object service) { + public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) { // do nothing } } diff --git a/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java b/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java index 5f2238ac1..58533e28e 100644 --- a/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java +++ b/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java @@ -7,7 +7,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -50,8 +49,10 @@ import org.redkale.mq.MessageConext; import org.redkale.mq.MessageConsumer; import org.redkale.mq.Messaged; import org.redkale.mq.ResourceConsumer; +import org.redkale.mq.spi.DynForMessaged.DynForMessageds; import org.redkale.service.LoadMode; import org.redkale.util.RedkaleClassLoader; +import org.redkale.util.RedkaleClassLoader.DynBytesClassLoader; import org.redkale.util.RedkaleException; import org.redkale.util.TypeToken; import org.redkale.util.Utility; @@ -67,8 +68,6 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { private Map methodBeans; - private RedkaleClassLoader.DynBytesClassLoader newLoader; - private Map consumerBytes; public MessageAsmMethodBoost(boolean remote, Class serviceType, MessageModuleEngine messageEngine) { @@ -83,7 +82,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { @Override public AsmNewMethod doMethod( - ClassLoader classLoader, + DynBytesClassLoader classLoader, ClassWriter cw, Class serviceImplClass, String newDynName, @@ -324,55 +323,41 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { if (consumerBytes == null) { consumerBytes = new LinkedHashMap<>(); } - consumerBytes.put(innerFullName.replace('/', '.'), bytes); + consumerBytes.put(innerFullName, bytes); } @Override - public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { + public void doAfterMethods(DynBytesClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { if (Utility.isNotEmpty(consumerBytes)) { - AnnotationVisitor av = - cw.visitAnnotation(org.redkale.asm.Type.getDescriptor(DynForMessaged.class), true); - av.visit("value", org.redkale.asm.Type.getType("L" + newDynName.replace('.', '/') + ";")); - av.visitEnd(); + AnnotationVisitor av0 = cw.visitAnnotation(org.redkale.asm.Type.getDescriptor(DynForMessageds.class), true); + AnnotationVisitor av1 = av0.visitArray("value"); + consumerBytes.forEach((innerFullName, bytes) -> { + String clzName = innerFullName.replace('/', '.'); + Class clazz = classLoader.loadClass(clzName, bytes); + RedkaleClassLoader.putDynClass(clzName, bytes, clazz); + AnnotationVisitor av2 = + av1.visitAnnotation(null, org.redkale.asm.Type.getDescriptor(DynForMessaged.class)); + av2.visit("value", org.redkale.asm.Type.getType("L" + innerFullName + ";")); + av2.visitEnd(); + }); + av1.visitEnd(); + av0.visitEnd(); } } @Override - public void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, Object service) { + public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) { DynForMessaged[] dyns = service.getClass().getAnnotationsByType(DynForMessaged.class); - if (Utility.isEmpty(dyns)) { - return; - } - try { - if (Utility.isNotEmpty(consumerBytes)) { - if (newLoader == null) { - if (classLoader instanceof RedkaleClassLoader.DynBytesClassLoader) { - newLoader = (RedkaleClassLoader.DynBytesClassLoader) classLoader; - } else { - newLoader = new RedkaleClassLoader.DynBytesClassLoader( - classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader); - } - } - List> consumers = new ArrayList<>(); - consumerBytes.forEach((clzName, bytes) -> { - Class clazz = (Class) newLoader.loadClass(clzName, bytes); - RedkaleClassLoader.putDynClass(clzName, bytes, clazz); - consumers.add(clazz); - }); - for (Class clazz : consumers) { - MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service); - messageEngine.addMessageConsumer(consumer); - } - } else { + if (Utility.isNotEmpty(dyns)) { + try { for (DynForMessaged item : dyns) { Class clazz = item.value(); MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service); messageEngine.addMessageConsumer(consumer); } + } catch (Exception e) { + throw new RedkaleException(e); } - - } catch (Exception e) { - throw new RedkaleException(e); } } } diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index d3cfeabf2..797150920 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -28,6 +28,7 @@ import org.redkale.scheduled.Scheduled; import org.redkale.service.*; import org.redkale.util.AnyValue; import org.redkale.util.RedkaleClassLoader; +import org.redkale.util.RedkaleClassLoader.DynBytesClassLoader; import org.redkale.util.TypeToken; import org.redkale.util.Uint128; import org.redkale.util.Utility; @@ -493,7 +494,7 @@ public abstract class Sncp { */ @SuppressWarnings("unchecked") protected static Class createLocalServiceClass( - ClassLoader classLoader, + DynBytesClassLoader dynLoader, final String name, final Class serviceImplClass, final AsmMethodBoost methodBoost) { @@ -513,7 +514,6 @@ public abstract class Sncp { final String resDesc = Type.getDescriptor(Resource.class); final String anyValueDesc = Type.getDescriptor(AnyValue.class); final String sncpDynDesc = Type.getDescriptor(SncpDyn.class); - ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader; // String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + LOCALPREFIX + // serviceImplClass.getSimpleName(); String newDynName = "org/redkaledyn/service/local/_DynLocalService__" @@ -533,7 +533,7 @@ public abstract class Sncp { if (methodBoost == null) { // 加强动态时不能重复加载 try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - return (Class) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz); + return (Class) (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); } catch (ClassNotFoundException e) { // do nothing } catch (Throwable t) { @@ -595,8 +595,8 @@ public abstract class Sncp { mv.visitEnd(); } if (methodBoost != null) { - createNewMethods(classLoader, serviceImplClass, methodBoost, new HashSet<>(), cw, newDynName, supDynName); - methodBoost.doAfterMethods(classLoader, cw, newDynName, FIELDPREFIX); + createNewMethods(dynLoader, serviceImplClass, methodBoost, new HashSet<>(), cw, newDynName, supDynName); + methodBoost.doAfterMethods(dynLoader, cw, newDynName, FIELDPREFIX); } cw.visitEnd(); byte[] bytes = cw.toByteArray(); @@ -604,17 +604,13 @@ public abstract class Sncp { if (methodBoost != null) { try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - newClazz = (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz); + newClazz = (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); } catch (Throwable t) { // do nothing } } if (newClazz == null) { - newClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); + newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes); } RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); RedkaleClassLoader.putReflectionPublicClasses(newDynName.replace('/', '.')); @@ -637,7 +633,7 @@ public abstract class Sncp { } private static void createNewMethods( - ClassLoader classLoader, + DynBytesClassLoader classLoader, Class clazz, final AsmMethodBoost methodBoost, Set methodKeys, @@ -777,7 +773,8 @@ public abstract class Sncp { final String remoteGroup, final AnyValue conf) { try { - final Class newClazz = createLocalServiceClass(classLoader, name, serviceImplClass, methodBoost); + final DynBytesClassLoader dynLoader = DynBytesClassLoader.create(classLoader); + final Class newClazz = createLocalServiceClass(dynLoader, name, serviceImplClass, methodBoost); T service = (T) newClazz.getDeclaredConstructor().newInstance(); // -------------------------------------- Service remoteService = null; @@ -829,7 +826,7 @@ public abstract class Sncp { } if (methodBoost != null) { // 必须用servcie的ClassLoader, 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致 - methodBoost.doInstance(service.getClass().getClassLoader(), resourceFactory, service); + methodBoost.doInstance(dynLoader, resourceFactory, service); } return service; } catch (RuntimeException rex) { @@ -949,7 +946,7 @@ public abstract class Sncp { final String sncpInfoDesc = Type.getDescriptor(SncpRemoteInfo.class); final String sncpDynDesc = Type.getDescriptor(SncpDyn.class); final String anyValueDesc = Type.getDescriptor(AnyValue.class); - final ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader; + final DynBytesClassLoader dynLoader = DynBytesClassLoader.create(classLoader); String newDynName = "org/redkaledyn/service/remote/_DynRemoteService__" + serviceTypeOrImplClass.getName().replace('.', '_').replace('$', '_'); if (!name.isEmpty()) { @@ -966,7 +963,7 @@ public abstract class Sncp { } try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz; + Class newClazz = clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz; T service = (T) newClazz.getDeclaredConstructor().newInstance(); { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); @@ -985,7 +982,7 @@ public abstract class Sncp { } if (methodBoost != null) { // 必须用servcie的ClassLoader, 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致 - methodBoost.doInstance(service.getClass().getClassLoader(), resourceFactory, service); + methodBoost.doInstance(dynLoader, resourceFactory, service); } return service; } catch (Throwable ex) { @@ -1111,7 +1108,7 @@ public abstract class Sncp { if (methodBoost != null) { List> filterAnns = methodBoost.filterMethodAnnotations(method); newMethod = methodBoost.doMethod( - classLoader, cw, serviceTypeOrImplClass, newDynName, FIELDPREFIX, filterAnns, method, null); + dynLoader, cw, serviceTypeOrImplClass, newDynName, FIELDPREFIX, filterAnns, method, null); } if (newMethod != null) { acc = newMethod.getMethodAccs(); @@ -1238,16 +1235,12 @@ public abstract class Sncp { mv.visitEnd(); } if (methodBoost != null) { - createNewMethods(classLoader, serviceTypeOrImplClass, methodBoost, methodKeys, cw, newDynName, supDynName); - methodBoost.doAfterMethods(classLoader, cw, newDynName, FIELDPREFIX); + createNewMethods(dynLoader, serviceTypeOrImplClass, methodBoost, methodKeys, cw, newDynName, supDynName); + methodBoost.doAfterMethods(dynLoader, cw, newDynName, FIELDPREFIX); } cw.visitEnd(); byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); + Class newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes); RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.')); RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); @@ -1273,7 +1266,7 @@ public abstract class Sncp { } if (methodBoost != null) { // 必须用servcie的ClassLoader, 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致 - methodBoost.doInstance(service.getClass().getClassLoader(), resourceFactory, service); + methodBoost.doInstance(dynLoader, resourceFactory, service); } return service; } catch (Exception ex) { diff --git a/src/main/java/org/redkale/util/RedkaleClassLoader.java b/src/main/java/org/redkale/util/RedkaleClassLoader.java index 59de139ac..faf46ee3c 100644 --- a/src/main/java/org/redkale/util/RedkaleClassLoader.java +++ b/src/main/java/org/redkale/util/RedkaleClassLoader.java @@ -587,6 +587,15 @@ public class RedkaleClassLoader extends URLClassLoader { super(parent); } + public static DynBytesClassLoader create(ClassLoader parent) { + if (parent == null) { + parent = Thread.currentThread().getContextClassLoader(); + } + return parent instanceof DynBytesClassLoader + ? (DynBytesClassLoader) parent + : new DynBytesClassLoader(parent); + } + @Override public Class findClass(String name) throws ClassNotFoundException { byte[] classData = classes.get(name);