MessageAsmMethodBoost优化

This commit is contained in:
redkale
2024-08-12 23:49:25 +08:00
parent cebd463d58
commit aee5745172
11 changed files with 140 additions and 78 deletions

View File

@@ -171,7 +171,7 @@
<executions>
<execution>
<goals>
<goal>apply</goal>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>

View File

@@ -96,10 +96,10 @@ public abstract class AsmMethodBoost<T> {
* @param fieldPrefix 动态字段的前缀
* @param filterAnns 需要过滤的注解
* @param method 操作的方法
* @param newMethodName 新的方法名, 可能为null
* @param newMethod 新的方法名, 可能为null
* @return 下一个新的方法名不做任何处理应返回参数newMethodName
*/
public abstract String doMethod(
public abstract AsmNewMethod doMethod(
ClassLoader classLoader,
ClassWriter cw,
Class serviceImplClass,
@@ -107,7 +107,7 @@ public abstract class AsmMethodBoost<T> {
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
@Nullable String newMethodName);
@Nullable AsmNewMethod newMethod);
/**
* 处理所有动态方法后调用
@@ -134,24 +134,24 @@ public abstract class AsmMethodBoost<T> {
}
protected MethodVisitor createMethodVisitor(
ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) {
ClassWriter cw, Method method, AsmNewMethod newMethod, int newMethodAcc, AsmMethodBean methodBean) {
return new MethodDebugVisitor(cw.visitMethod(
getAcc(method, newMethodName),
getNowMethodName(method, newMethodName),
getAcc(method, newMethod),
getNowMethodName(method, newMethod),
Type.getMethodDescriptor(method),
getMethodSignature(method, methodBean),
getMethodExceptions(method, methodBean)));
}
protected int getAcc(Method method, String newMethodName) {
if (newMethodName != null) {
protected int getAcc(Method method, AsmNewMethod newMethod) {
if (newMethod != null) {
return ACC_PRIVATE;
}
return Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
}
protected String getNowMethodName(Method method, String newMethodName) {
return newMethodName == null ? method.getName() : newMethodName;
protected String getNowMethodName(Method method, AsmNewMethod newMethod) {
return newMethod == null ? method.getName() : newMethod.getMethodName();
}
protected String getMethodSignature(Method method, AsmMethodBean methodBean) {
@@ -175,13 +175,13 @@ public abstract class AsmMethodBoost<T> {
}
protected void visitRawAnnotation(
Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) {
Method method, AsmNewMethod newMethod, MethodVisitor mv, Class skipAnnType, List skipAnns) {
if (newMethod == null) {
// 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
if (ann.annotationType() != skipAnnType
&& (skipAnns == null || !skipAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(
mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true),
ann.annotationType(),
@@ -305,7 +305,7 @@ public abstract class AsmMethodBoost<T> {
}
@Override
public String doMethod(
public AsmNewMethod doMethod(
ClassLoader classLoader,
ClassWriter cw,
Class serviceImplClass,
@@ -313,22 +313,15 @@ public abstract class AsmMethodBoost<T> {
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
String newMethodName) {
String newName = newMethodName;
AsmNewMethod newMethod) {
AsmNewMethod newResult = newMethod;
for (AsmMethodBoost item : items) {
if (item != null) {
newName = item.doMethod(
classLoader,
cw,
serviceImplClass,
newDynName,
fieldPrefix,
filterAnns,
method,
newName);
newResult = item.doMethod(
classLoader, cw, serviceImplClass, newDynName, fieldPrefix, filterAnns, method, newResult);
}
}
return newName;
return newResult;
}
@Override

View File

@@ -0,0 +1,47 @@
/*
*/
package org.redkale.asm;
import org.redkale.convert.json.JsonConvert;
/**
* 存放新方法的信息
*
* @since 2.8.0
*/
public class AsmNewMethod {
private String methodName;
private int methodAccs;
public AsmNewMethod() {}
public AsmNewMethod(String newName, int newAccs) {
this.methodName = newName;
this.methodAccs = newAccs;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public int getMethodAccs() {
return methodAccs;
}
public void setMethodAccs(int methodAccs) {
this.methodAccs = methodAccs;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1139,6 +1139,7 @@ public final class Application {
if (list == null) {
return null;
}
Utility.sortPriority(list);
return list.size() == 1 ? list.get(0) : AsmMethodBoost.create(remote, list);
}

View File

@@ -16,6 +16,7 @@ import java.util.logging.Logger;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.AsmNewMethod;
import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter;
import org.redkale.asm.FieldVisitor;
@@ -60,7 +61,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
}
@Override
public String doMethod(
public AsmNewMethod doMethod(
final ClassLoader classLoader,
final ClassWriter cw,
final Class serviceImplClass,
@@ -68,7 +69,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
final String fieldPrefix,
final List filterAnns,
final Method method,
final String newMethodName) {
final AsmNewMethod newMethod) {
Map<String, CachedAction> actions = this.actionMap;
if (actions == null) {
actions = new LinkedHashMap<>();
@@ -76,13 +77,13 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
}
Cached cached = method.getAnnotation(Cached.class);
if (cached == null) {
return newMethodName;
}
if (!LoadMode.matches(remote, cached.mode())) {
return newMethodName;
return newMethod;
}
if (method.getAnnotation(DynForCached.class) != null) {
return newMethodName;
return newMethod;
}
if (!LoadMode.matches(remote, cached.mode())) {
return newMethod;
}
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException(
@@ -102,12 +103,12 @@ 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, newMethodName, methodBean);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean);
// mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, DynForCached.class, cached);
visitRawAnnotation(method, newMethodName, mv, Cached.class, filterAnns);
visitRawAnnotation(method, newMethod, mv, Cached.class, filterAnns);
Label l0 = new Label();
mv.visitLabel(l0);
@@ -210,7 +211,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
"Lookup",
ACC_PUBLIC + ACC_FINAL + ACC_STATIC);
}
return rsMethodName;
return new AsmNewMethod(rsMethodName, ACC_PRIVATE);
}
@Override

View File

@@ -10,6 +10,7 @@ import java.util.List;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.AsmNewMethod;
import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter;
import org.redkale.asm.Label;
@@ -36,7 +37,7 @@ public class LockedAsmMethodBoost extends AsmMethodBoost {
}
@Override
public String doMethod(
public AsmNewMethod doMethod(
ClassLoader classLoader,
ClassWriter cw,
Class serviceImplClass,
@@ -44,16 +45,16 @@ public class LockedAsmMethodBoost extends AsmMethodBoost {
String fieldPrefix,
List filterAnns,
Method method,
final String newMethodName) {
final AsmNewMethod newMethod) {
Locked locked = method.getAnnotation(Locked.class);
if (locked == null) {
return newMethodName;
return newMethod;
}
if (!LoadMode.matches(remote, locked.mode())) {
return newMethodName;
return newMethod;
}
if (method.getAnnotation(DynForLocked.class) != null) {
return newMethodName;
return newMethod;
}
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException(
@@ -70,14 +71,14 @@ 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, newMethodName, methodBean);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethod, ACC_PRIVATE, methodBean);
// mv.setDebug(true);
Label l0 = new Label();
mv.visitLabel(l0);
AnnotationVisitor av = mv.visitAnnotation(lockDynDesc, true);
av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, DynForLocked.class, locked);
visitRawAnnotation(method, newMethodName, mv, Locked.class, filterAnns);
visitRawAnnotation(method, newMethod, mv, Locked.class, filterAnns);
mv.visitVarInsn(ALOAD, 0);
List<Integer> insns = visitVarInsnParamTypes(mv, method, 0);
mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, Type.getMethodDescriptor(method), false);
@@ -85,7 +86,7 @@ public class LockedAsmMethodBoost extends AsmMethodBoost {
mv.visitMaxs(20, 20);
mv.visitEnd();
}
return rsMethodName;
return new AsmNewMethod(rsMethodName, ACC_PRIVATE);
}
@Override

View File

@@ -21,8 +21,8 @@ import org.redkale.mq.MessageConsumer;
@Documented
@Target({TYPE})
@Retention(RUNTIME)
@Repeatable(DynForMessage.DynForMessages.class)
public @interface DynForMessage {
@Repeatable(DynForMessaged.DynForMessageds.class)
public @interface DynForMessaged {
Class<? extends MessageConsumer> value();
@@ -30,8 +30,8 @@ public @interface DynForMessage {
@Documented
@Target({TYPE})
@Retention(RUNTIME)
@interface DynForMessages {
@interface DynForMessageds {
DynForMessage[] value();
DynForMessaged[] value();
}
}

View File

@@ -16,6 +16,7 @@ import org.redkale.annotation.AutoLoad;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.AsmNewMethod;
import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter;
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
@@ -81,7 +82,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
}
@Override
public String doMethod(
public AsmNewMethod doMethod(
ClassLoader classLoader,
ClassWriter cw,
Class serviceImplClass,
@@ -89,25 +90,30 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
String fieldPrefix,
List filterAnns,
Method method,
String newMethodName) {
if (serviceType.getAnnotation(DynForMessage.class) != null) {
return newMethodName;
AsmNewMethod newMethod) {
if (serviceType.getAnnotation(DynForMessaged.class) != null) {
return newMethod;
}
Messaged messaged = method.getAnnotation(Messaged.class);
if (messaged == null) {
return newMethodName;
return newMethod;
}
if (!LoadMode.matches(remote, messaged.mode())) {
return newMethodName;
return newMethod;
}
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException(
"@" + Messaged.class.getSimpleName() + " cannot on final or static method, but on " + method);
}
if (Modifier.isProtected(method.getModifiers()) && Modifier.isFinal(method.getModifiers())) {
throw new RedkaleException(
"@" + Messaged.class.getSimpleName() + " cannot on protected final method, but on " + method);
}
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
throw new RedkaleException(
"@" + Messaged.class.getSimpleName() + " must on protected or public method, but on " + method);
}
int paramCount = method.getParameterCount();
if (paramCount != 1 && paramCount != 2) {
throw new RedkaleException(
@@ -135,9 +141,8 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
ConvertFactory factory =
ConvertFactory.findConvert(messaged.convertType()).getFactory();
factory.loadDecoder(messageType);
createInnerConsumer(
cw, method, paramKind, TypeToken.typeToClass(messageType), messaged, newDynName, newMethodName);
return newMethodName;
createInnerConsumer(cw, method, paramKind, TypeToken.typeToClass(messageType), messaged, newDynName, newMethod);
return newMethod;
}
// paramKind: 1:单个MessageType; 2: MessageConext & MessageType; 3: MessageType & MessageConext;
@@ -148,7 +153,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
Class msgType,
Messaged messaged,
String newDynName,
String newMethodName) {
AsmNewMethod newMethod) {
final String newDynDesc = "L" + newDynName + ";";
final String innerClassName = "Dyn" + MessageConsumer.class.getSimpleName() + index.incrementAndGet();
final String innerFullName = newDynName + "$" + innerClassName;
@@ -221,7 +226,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
mv.visitEnd();
}
{
String methodName = newMethodName == null ? method.getName() : newMethodName;
String methodName = newMethod == null ? method.getName() : newMethod.getMethodName();
mv = cw.visitMethod(
ACC_PUBLIC,
"onMessage",
@@ -325,7 +330,8 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
@Override
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {
if (Utility.isNotEmpty(consumerBytes)) {
AnnotationVisitor av = cw.visitAnnotation(org.redkale.asm.Type.getDescriptor(DynForMessage.class), true);
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();
}
@@ -333,7 +339,7 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
@Override
public void doInstance(ClassLoader classLoader, ResourceFactory resourceFactory, Object service) {
DynForMessage[] dyns = service.getClass().getAnnotationsByType(DynForMessage.class);
DynForMessaged[] dyns = service.getClass().getAnnotationsByType(DynForMessaged.class);
if (Utility.isEmpty(dyns)) {
return;
}
@@ -358,12 +364,13 @@ public class MessageAsmMethodBoost extends AsmMethodBoost {
messageEngine.addMessageConsumer(consumer);
}
} else {
for (DynForMessage item : dyns) {
for (DynForMessaged item : dyns) {
Class<? extends MessageConsumer> clazz = item.value();
MessageConsumer consumer = (MessageConsumer) clazz.getConstructors()[0].newInstance(service);
messageEngine.addMessageConsumer(consumer);
}
}
} catch (Exception e) {
throw new RedkaleException(e);
}

View File

@@ -658,9 +658,9 @@ public abstract class Sncp {
}
methodKeys.add(mk);
List<Class<? extends Annotation>> filterAnns = methodBoost.filterMethodAnnotations(method);
String newMethodName =
AsmNewMethod newMethod =
methodBoost.doMethod(classLoader, cw, clazz, newDynName, FIELDPREFIX, filterAnns, method, null);
if (newMethodName != null) {
if (newMethod != null) {
String desc = Type.getMethodDescriptor(method);
AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method);
String signature = null;
@@ -678,8 +678,8 @@ public abstract class Sncp {
exceptions = methodBean.getExceptions();
}
// 需要定义一个新方法调用 super.method
mv = new MethodDebugVisitor(
cw.visitMethod(ACC_PRIVATE, newMethodName, desc, signature, exceptions));
mv = new MethodDebugVisitor(cw.visitMethod(
newMethod.getMethodAccs(), newMethod.getMethodName(), desc, signature, exceptions));
Label l0 = new Label();
mv.visitLabel(l0);
// mv.setDebug(true);
@@ -1106,14 +1106,16 @@ public abstract class Sncp {
methodKeys.add(mk);
int acc = ACC_PUBLIC;
AsmNewMethod newMethod = null;
String newMethodName = null;
if (methodBoost != null) {
List<Class<? extends Annotation>> filterAnns = methodBoost.filterMethodAnnotations(method);
newMethodName = methodBoost.doMethod(
newMethod = methodBoost.doMethod(
classLoader, cw, serviceTypeOrImplClass, newDynName, FIELDPREFIX, filterAnns, method, null);
}
if (newMethodName != null) {
acc = ACC_PRIVATE;
if (newMethod != null) {
acc = newMethod.getMethodAccs();
newMethodName = newMethod.getMethodName();
} else {
newMethodName = method.getName();
}

View File

@@ -3,7 +3,6 @@
package org.redkale.util;
import java.util.*;
import org.redkale.annotation.Priority;
/**
* 配置源Agent的Provider
@@ -22,11 +21,6 @@ public interface InstanceProvider<V> {
// 值大排前面
public static <P extends InstanceProvider> List<P> sort(List<P> providers) {
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
return providers;
return Utility.sortPriority(providers);
}
}

View File

@@ -26,6 +26,7 @@ import java.util.zip.GZIPInputStream;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import org.redkale.annotation.ClassDepends;
import org.redkale.annotation.Priority;
import org.redkale.convert.json.JsonConvert;
/**
@@ -1721,6 +1722,21 @@ public final class Utility {
return 0;
}
/**
* 排序, 值大排前面
* @param <P> 泛型
* @param list 集合
* @return 排序后的集合
*/
public static <P> List<P> sortPriority(List<P> list) {
Collections.sort(list, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
return list;
}
/**
* 将一个或多个新元素添加到数组开始,数组中的元素自动后移
*