DynForCache

This commit is contained in:
redkale
2023-12-20 18:13:39 +08:00
parent 0c1e34c2cc
commit ff7ed50e82
4 changed files with 75 additions and 36 deletions

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();