diff --git a/src/main/java/org/redkale/asm/AsmMethodBoost.java b/src/main/java/org/redkale/asm/AsmMethodBoost.java index 21508eb33..b7c410b0c 100644 --- a/src/main/java/org/redkale/asm/AsmMethodBoost.java +++ b/src/main/java/org/redkale/asm/AsmMethodBoost.java @@ -4,7 +4,9 @@ package org.redkale.asm; import java.io.InputStream; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -44,18 +46,29 @@ public interface AsmMethodBoost { return rs; } + /** + * 获取需屏蔽的方法上的注解 + * + * @param method 方法 + * + * @return 需要屏蔽的注解 + */ + public List> filterMethodAnnotations(Method method); + /** * 对方法进行动态加强处理 * * @param cw 动态字节码Writer * @param newDynName 动态新类名 * @param fieldPrefix 动态字段的前缀 + * @param filterAnns 需要过滤的注解 * @param method 操作的方法 * @param newMethodName 新的方法名, 可能为null * * @return 下一个新的方法名,不做任何处理应返回参数newMethodName */ - public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, Method method, @Nullable String newMethodName); + public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, + List> filterAnns, Method method, @Nullable String newMethodName); /** 处理所有动态方法后调用 * @@ -92,11 +105,29 @@ public interface AsmMethodBoost { } @Override - public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, Method method, String newMethodName) { + public List> filterMethodAnnotations(Method method) { + List> list = null; + for (AsmMethodBoost item : items) { + if (item != null) { + List> sub = item.filterMethodAnnotations(method); + if (sub != null) { + if (list == null) { + list = new ArrayList<>(); + } + list.addAll(sub); + } + } + } + return list; + } + + @Override + public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, + List> filterAnns, Method method, String newMethodName) { String newName = newMethodName; for (AsmMethodBoost item : items) { if (item != null) { - newName = item.doMethod(cw, newDynName, fieldPrefix, method, newName); + newName = item.doMethod(cw, newDynName, fieldPrefix, filterAnns, method, newName); } } return newName; diff --git a/src/main/java/org/redkale/cache/spi/CacheAsmMethodBoost.java b/src/main/java/org/redkale/cache/spi/CacheAsmMethodBoost.java index 4772af7d3..eab088601 100644 --- a/src/main/java/org/redkale/cache/spi/CacheAsmMethodBoost.java +++ b/src/main/java/org/redkale/cache/spi/CacheAsmMethodBoost.java @@ -41,6 +41,8 @@ import org.redkale.util.RedkaleException; */ public class CacheAsmMethodBoost implements AsmMethodBoost { + private static final List> FILTER_ANN = List.of(Cached.class); + protected final Class serviceType; public CacheAsmMethodBoost(Class serviceType) { @@ -48,7 +50,12 @@ public class CacheAsmMethodBoost implements AsmMethodBoost { } @Override - public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, Method method, final String newMethodName) { + public List> filterMethodAnnotations(Method method) { + return FILTER_ANN; + } + + @Override + public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) { Cached cached = method.getAnnotation(Cached.class); if (cached == null) { return newMethodName; @@ -69,7 +76,7 @@ public class CacheAsmMethodBoost implements AsmMethodBoost { nowMethodName = newMethodName; } - final String rsMethodName = method.getName() + "_cache"; + final String rsMethodName = method.getName() + "_afterCache"; { Map methodBeans = AsmMethodBoost.getMethodBeans(serviceType); AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method); @@ -96,20 +103,21 @@ public class CacheAsmMethodBoost implements AsmMethodBoost { //mv.setDebug(true); Label l0 = new Label(); mv.visitLabel(l0); - { - av = mv.visitAnnotation(cacheDynDesc, true); - av.visitEnd(); + av = mv.visitAnnotation(cacheDynDesc, true); + av.visitEnd(); + if (newMethodName == null) { + //给方法加上原有的Annotation final Annotation[] anns = method.getAnnotations(); for (Annotation ann : anns) { - if (ann.annotationType() != Cached.class) { + if (ann.annotationType() != Cached.class + && (filterAnns == null || !filterAnns.contains(ann.annotationType()))) { Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); } } - } - { //给参数加上原有的Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { + //给参数加上原有的Annotation + final Annotation[][] annss = method.getParameterAnnotations(); + for (int k = 0; k < annss.length; k++) { + for (Annotation ann : annss[k]) { Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); } } diff --git a/src/main/java/org/redkale/lock/spi/LockAsmMethodBoost.java b/src/main/java/org/redkale/lock/spi/LockAsmMethodBoost.java index 3c5988800..18dbc6dcb 100644 --- a/src/main/java/org/redkale/lock/spi/LockAsmMethodBoost.java +++ b/src/main/java/org/redkale/lock/spi/LockAsmMethodBoost.java @@ -27,6 +27,8 @@ import org.redkale.util.RedkaleException; */ public class LockAsmMethodBoost implements AsmMethodBoost { + private static final List> FILTER_ANN = List.of(Locked.class); + protected final Class serviceType; public LockAsmMethodBoost(Class serviceType) { @@ -34,7 +36,12 @@ public class LockAsmMethodBoost implements AsmMethodBoost { } @Override - public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, Method method, final String newMethodName) { + public List> filterMethodAnnotations(Method method) { + return FILTER_ANN; + } + + @Override + public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) { Locked cached = method.getAnnotation(Locked.class); if (cached == null) { return newMethodName; @@ -55,12 +62,12 @@ public class LockAsmMethodBoost implements AsmMethodBoost { nowMethodName = newMethodName; } - final String rsMethodName = method.getName() + "_lock"; + final String rsMethodName = method.getName() + "_afterLock"; { Map methodBeans = AsmMethodBoost.getMethodBeans(serviceType); AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method); - final String cacheDynDesc = Type.getDescriptor(DynForLock.class); + final String lockDynDesc = Type.getDescriptor(DynForLock.class); MethodDebugVisitor mv; AnnotationVisitor av; String signature = null; @@ -82,20 +89,21 @@ public class LockAsmMethodBoost implements AsmMethodBoost { //mv.setDebug(true); Label l0 = new Label(); mv.visitLabel(l0); - { - av = mv.visitAnnotation(cacheDynDesc, true); - av.visitEnd(); + av = mv.visitAnnotation(lockDynDesc, true); + av.visitEnd(); + if (newMethodName == null) { + //给方法加上原有的Annotation final Annotation[] anns = method.getAnnotations(); for (Annotation ann : anns) { - if (ann.annotationType() != Locked.class) { + if (ann.annotationType() != Locked.class + && (filterAnns == null || !filterAnns.contains(ann.annotationType()))) { Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); } } - } - { //给参数加上原有的Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { + //给参数加上原有的Annotation + final Annotation[][] annss = method.getParameterAnnotations(); + for (int k = 0; k < annss.length; k++) { + for (Annotation ann : annss[k]) { Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); } } diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index edc91aa28..81b470091 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -568,7 +568,8 @@ public abstract class Sncp { continue; } methodKeys.add(mk); - String newMethodName = methodBoost.doMethod(cw, newDynName, FIELDPREFIX, method, null); + List> filterAnns = methodBoost.filterMethodAnnotations(method); + String newMethodName = methodBoost.doMethod(cw, newDynName, FIELDPREFIX, filterAnns, method, null); if (newMethodName != null) { String desc = Type.getMethodDescriptor(method); AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method); @@ -586,20 +587,11 @@ public abstract class Sncp { signature = methodBean.getSignature(); exceptions = methodBean.getExceptions(); } - //注意: 新方法会丢失原方法中的泛型信息signature //需要定义一个新方法调用 super.method mv = new MethodDebugVisitor(cw.visitMethod(ACC_PRIVATE, newMethodName, desc, signature, exceptions)); Label l0 = new Label(); mv.visitLabel(l0); //mv.setDebug(true); - { //给参数加上原有的Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { - Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); - } - } - } mv.visitVarInsn(ALOAD, 0); //传参数 Class[] paramTypes = method.getParameterTypes();