DynForCache
This commit is contained in:
@@ -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<T> {
|
||||
return rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需屏蔽的方法上的注解
|
||||
*
|
||||
* @param method 方法
|
||||
*
|
||||
* @return 需要屏蔽的注解
|
||||
*/
|
||||
public List<Class<? extends Annotation>> 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<Class<? extends Annotation>> filterAnns, Method method, @Nullable String newMethodName);
|
||||
|
||||
/** 处理所有动态方法后调用
|
||||
*
|
||||
@@ -92,11 +105,29 @@ public interface AsmMethodBoost<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doMethod(ClassWriter cw, String newDynName, String fieldPrefix, Method method, String newMethodName) {
|
||||
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method) {
|
||||
List<Class<? extends Annotation>> list = null;
|
||||
for (AsmMethodBoost item : items) {
|
||||
if (item != null) {
|
||||
List<Class<? extends Annotation>> 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<Class<? extends Annotation>> 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;
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.redkale.util.RedkaleException;
|
||||
*/
|
||||
public class CacheAsmMethodBoost implements AsmMethodBoost {
|
||||
|
||||
private static final List<Class<? extends Annotation>> 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<Class<? extends Annotation>> 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<String, AsmMethodBean> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.redkale.util.RedkaleException;
|
||||
*/
|
||||
public class LockAsmMethodBoost implements AsmMethodBoost {
|
||||
|
||||
private static final List<Class<? extends Annotation>> 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<Class<? extends Annotation>> 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<String, AsmMethodBean> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,8 @@ public abstract class Sncp {
|
||||
continue;
|
||||
}
|
||||
methodKeys.add(mk);
|
||||
String newMethodName = methodBoost.doMethod(cw, newDynName, FIELDPREFIX, method, null);
|
||||
List<Class<? extends Annotation>> 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();
|
||||
|
||||
Reference in New Issue
Block a user