diff --git a/src/main/java/org/redkale/asm/AsmMethodBoost.java b/src/main/java/org/redkale/asm/AsmMethodBoost.java index 1d212067c..3146e4ecd 100644 --- a/src/main/java/org/redkale/asm/AsmMethodBoost.java +++ b/src/main/java/org/redkale/asm/AsmMethodBoost.java @@ -153,7 +153,7 @@ public abstract class AsmMethodBoost { } protected MethodVisitor createMethodVisitor( - ClassWriter cw, Method method, AsmNewMethod newMethod, int newMethodAcc, AsmMethodBean methodBean) { + ClassWriter cw, Method method, AsmNewMethod newMethod, AsmMethodBean methodBean) { return new MethodDebugVisitor(cw.visitMethod( getAcc(method, newMethod), getNowMethodName(method, newMethod), @@ -162,7 +162,7 @@ public abstract class AsmMethodBoost { getMethodExceptions(method, methodBean))); } - protected int getAcc(Method method, AsmNewMethod newMethod) { + protected final int getAcc(Method method, AsmNewMethod newMethod) { if (newMethod != null) { return ACC_PRIVATE; } diff --git a/src/main/java/org/redkale/asm/MethodDebugVisitor.java b/src/main/java/org/redkale/asm/MethodDebugVisitor.java index bf19e7976..46f2cc51f 100644 --- a/src/main/java/org/redkale/asm/MethodDebugVisitor.java +++ b/src/main/java/org/redkale/asm/MethodDebugVisitor.java @@ -193,8 +193,9 @@ public class MethodDebugVisitor extends MethodVisitor { public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { visitor.visitLocalVariable(name, desc, signature, start, end, index); if (debug) { - System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature - + "\", null, null, " + index + ");"); + String s = signature == null ? null : ("\"" + signature + "\""); + System.out.println( + "mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", " + s + ", null, null, " + index + ");"); } } diff --git a/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java b/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java index d2df1d39c..d2a6b3555 100644 --- a/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java +++ b/src/main/java/org/redkale/cached/spi/CachedAsmMethodBoost.java @@ -104,7 +104,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost { final AsmMethodBean methodBean = getMethodBean(method); { // 定义一个新方法调用 this.rsMethodName final String cacheDynDesc = Type.getDescriptor(DynForCached.class); - final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean); + final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean); // mv.setDebug(true); AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true); av.visit("dynField", dynFieldName); diff --git a/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java b/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java index 9e46cac76..028ee33a7 100644 --- a/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java +++ b/src/main/java/org/redkale/locked/spi/LockedAsmMethodBoost.java @@ -72,7 +72,7 @@ public class LockedAsmMethodBoost extends AsmMethodBoost { { // 定义一个新方法调用 this.rsMethodName final AsmMethodBean methodBean = getMethodBean(method); final String lockDynDesc = Type.getDescriptor(DynForLocked.class); - final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean); + final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean); // mv.setDebug(true); Label l0 = new Label(); mv.visitLabel(l0); diff --git a/src/main/java/org/redkale/mq/spi/DynForMessaged.java b/src/main/java/org/redkale/mq/spi/DynForMessaged.java index 284e16363..50cbedc70 100644 --- a/src/main/java/org/redkale/mq/spi/DynForMessaged.java +++ b/src/main/java/org/redkale/mq/spi/DynForMessaged.java @@ -24,8 +24,6 @@ import org.redkale.mq.MessageConsumer; @Repeatable(DynForMessaged.DynForMessageds.class) public @interface DynForMessaged { - String dynField(); - Class consumer(); @Inherited diff --git a/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java b/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java index 60bd6b771..083e29230 100644 --- a/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java +++ b/src/main/java/org/redkale/mq/spi/MessageAsmMethodBoost.java @@ -4,7 +4,6 @@ package org.redkale.mq.spi; import java.lang.annotation.Annotation; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; @@ -44,6 +43,7 @@ import static org.redkale.asm.Opcodes.POP; import static org.redkale.asm.Opcodes.PUTFIELD; import static org.redkale.asm.Opcodes.RETURN; import static org.redkale.asm.Opcodes.V11; +import org.redkale.convert.Convert; import org.redkale.convert.ConvertFactory; import org.redkale.inject.ResourceFactory; import org.redkale.mq.MessageConext; @@ -101,9 +101,9 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { if (!LoadMode.matches(remote, messaged.mode())) { return newMethod; } - if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { + if (Modifier.isStatic(method.getModifiers())) { throw new RedkaleException( - "@" + Messaged.class.getSimpleName() + " cannot on final or static method, but on " + method); + "@" + Messaged.class.getSimpleName() + " cannot on static method, but on " + method); } if (Modifier.isProtected(method.getModifiers()) && Modifier.isFinal(method.getModifiers())) { throw new RedkaleException( @@ -138,16 +138,36 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { + MessageConext.class.getSimpleName() + " parameter type, but on " + method); } } - ConvertFactory factory = - ConvertFactory.findConvert(messaged.convertType()).getFactory(); - factory.loadDecoder(messageType); + Convert convert = ConvertFactory.findConvert(messaged.convertType()); + convert.getFactory().loadDecoder(messageType); + if (Modifier.isProtected(method.getModifiers())) { + createMessageMethod(cw, method, serviceImplClass, filterAnns, newMethod); + } createInnerConsumer(cw, method, paramKind, TypeToken.typeToClass(messageType), messaged, newDynName, newMethod); return newMethod; } + private void createMessageMethod( + ClassWriter cw, Method method, Class serviceImplClass, List filterAnns, AsmNewMethod newMethod) { + final String serviceName = serviceImplClass.getName().replace('.', '/'); + final AsmMethodBean methodBean = getMethodBean(method); + final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, methodBean); + visitRawAnnotation(method, newMethod, mv, Messaged.class, filterAnns); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitVarInsn(ALOAD, 0); + List insns = visitVarInsnParamTypes(mv, method, 0); + String methodDesc = org.redkale.asm.Type.getMethodDescriptor(method); + mv.visitMethodInsn(INVOKESPECIAL, serviceName, method.getName(), methodDesc, false); + visitInsnReturn(mv, method, l0, insns, methodBean); + int max = method.getParameterCount() + 1; + mv.visitMaxs(max, max); + mv.visitEnd(); + } + // paramKind: 1:单个MessageType; 2: MessageConext & MessageType; 3: MessageType & MessageConext; private void createInnerConsumer( - ClassWriter parentCW, + ClassWriter pcw, Method method, int paramKind, Class msgType, @@ -176,7 +196,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { genericMsgTypeDesc = methodSignature.substring(1, methodSignature.lastIndexOf(')')); // 获取()中的值 } - parentCW.visitInnerClass(innerFullName, newDynName, innerClassName, ACC_PUBLIC + ACC_STATIC); + pcw.visitInnerClass(innerFullName, newDynName, innerClassName, ACC_PUBLIC + ACC_STATIC); MethodVisitor mv; ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); @@ -339,55 +359,22 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { RedkaleClassLoader.putReflectionPublicConstructors(clazz, clzName); AnnotationVisitor av2 = av1.visitAnnotation(null, org.redkale.asm.Type.getDescriptor(DynForMessaged.class)); - av2.visit("dynField", getFieldName(innerFullName)); av2.visit("consumer", org.redkale.asm.Type.getType("L" + innerFullName + ";")); av2.visitEnd(); }); av1.visitEnd(); av0.visitEnd(); - String consumerDesc = org.redkale.asm.Type.getDescriptor(MessageConsumer.class); - consumerBytes.forEach((innerFullName, bytes) -> { - FieldVisitor fv = cw.visitField(ACC_PRIVATE, getFieldName(innerFullName), consumerDesc, null, null); - fv.visitEnd(); - }); } } - @Override - public void doConstructorMethod( - DynBytesClassLoader classLoader, - ClassWriter cw, - MethodVisitor mv, - String newDynName, - String fieldPrefix, - boolean remote) { - if (remote || Utility.isEmpty(consumerBytes)) { - return; - } - String consumerDesc = org.redkale.asm.Type.getDescriptor(MessageConsumer.class); - consumerBytes.forEach((innerFullName, bytes) -> { - mv.visitVarInsn(ALOAD, 0); - mv.visitTypeInsn(NEW, innerFullName); - mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, innerFullName, "", "(L" + newDynName + ";)V", false); - mv.visitFieldInsn(PUTFIELD, newDynName, getFieldName(innerFullName), consumerDesc); - }); - } - @Override public void doInstance(DynBytesClassLoader classLoader, ResourceFactory resourceFactory, Object service) { DynForMessaged[] dyns = service.getClass().getAnnotationsByType(DynForMessaged.class); if (Utility.isNotEmpty(dyns)) { try { for (DynForMessaged item : dyns) { - // Class clazz = item.value(); - // MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service); - String fieldName = item.dynField(); - Field field = service.getClass().getDeclaredField(fieldName); - RedkaleClassLoader.putReflectionField(service.getClass().getName(), field); - field.setAccessible(true); - MessageConsumer consumer = (MessageConsumer) field.get(service); + Class clazz = item.consumer(); + MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service); messageEngine.addMessageConsumer(consumer); } } catch (Exception e) { @@ -395,9 +382,4 @@ public class MessageAsmMethodBoost extends AsmMethodBoost { } } } - - private String getFieldName(String innerFullName) { - String simpleClassName = innerFullName.substring(innerFullName.lastIndexOf('$') + 1); - return "_dyn" + simpleClassName; - } } diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index cd7cbe305..b1dcdcdfa 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -486,7 +486,7 @@ public abstract class Sncp { * 创建Service的本地模式Class * * @param Service子类 - * @param classLoader ClassLoader + * @param dynLoader DynBytesClassLoader * @param name 资源名 * @param serviceImplClass Service类 * @param methodBoost 方法扩展 @@ -532,8 +532,9 @@ public abstract class Sncp { } if (methodBoost == null) { // 加强动态时不能重复加载 try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - return (Class) (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); + final String newDynClass = newDynName.replace('/', '.'); + Class clz = RedkaleClassLoader.findDynClass(newDynClass); + return (Class) (clz == null ? dynLoader.loadClass(newDynClass) : clz); } catch (ClassNotFoundException e) { // do nothing } catch (Throwable t) { @@ -603,27 +604,18 @@ public abstract class Sncp { } cw.visitEnd(); byte[] bytes = cw.toByteArray(); - Class newClazz = null; - if (methodBoost != null) { - try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - newClazz = (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz); - } catch (Throwable t) { - // do nothing - } - } - if (newClazz == null) { - newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes); - } - RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); - RedkaleClassLoader.putReflectionPublicClasses(newDynName.replace('/', '.')); - RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); + final String newDynClass = newDynName.replace('/', '.'); + Class newClazz = dynLoader.loadClass(newDynClass, bytes); + + RedkaleClassLoader.putDynClass(newDynClass, bytes, newClazz); + RedkaleClassLoader.putReflectionPublicClasses(newDynClass); + RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynClass); try { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); + RedkaleClassLoader.putReflectionField(newDynClass, c); c = newClazz.getDeclaredField(FIELDPREFIX + "_mq"); - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); + RedkaleClassLoader.putReflectionField(newDynClass, c); } catch (Exception e) { // do nothing } @@ -965,8 +957,9 @@ public abstract class Sncp { newDynName += "_" + (normal ? name : hash(name)); } try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - Class newClazz = clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz; + final String newDynClass = newDynName.replace('/', '.'); + Class clz = RedkaleClassLoader.findDynClass(newDynClass); + Class newClazz = clz == null ? dynLoader.loadClass(newDynClass) : clz; T service = (T) newClazz.getDeclaredConstructor().newInstance(); { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); @@ -1246,29 +1239,30 @@ public abstract class Sncp { } cw.visitEnd(); byte[] bytes = cw.toByteArray(); - Class newClazz = dynLoader.loadClass(newDynName.replace('/', '.'), bytes); - RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); - RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.')); - RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); + final String newDynClass = newDynName.replace('/', '.'); + Class newClazz = dynLoader.loadClass(newDynClass, bytes); + RedkaleClassLoader.putDynClass(newDynClass, bytes, newClazz); + RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynClass); + RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynClass); try { T service = (T) newClazz.getDeclaredConstructor().newInstance(); { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf"); c.setAccessible(true); c.set(service, conf); - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); + RedkaleClassLoader.putReflectionField(newDynClass, c); } { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_mq"); c.setAccessible(true); c.set(service, agent == null ? null : agent.getName()); - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); + RedkaleClassLoader.putReflectionField(newDynClass, c); } { Field c = newClazz.getDeclaredField(FIELDPREFIX + "_sncp"); c.setAccessible(true); c.set(service, info); - RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c); + RedkaleClassLoader.putReflectionField(newDynClass, c); } if (methodBoost != null) { // 必须用servcie的ClassLoader, 因为service是动态ClassLoader会与doMethod里的动态ClassLoader不一致