MessageAsmMethodBoost优化

This commit is contained in:
redkale
2024-08-13 11:25:14 +08:00
parent f694b617cf
commit cb9b57a04c
7 changed files with 60 additions and 85 deletions

View File

@@ -153,7 +153,7 @@ public abstract class AsmMethodBoost<T> {
}
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<T> {
getMethodExceptions(method, methodBean)));
}
protected int getAcc(Method method, AsmNewMethod newMethod) {
protected final int getAcc(Method method, AsmNewMethod newMethod) {
if (newMethod != null) {
return ACC_PRIVATE;
}

View File

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

View File

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

View File

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

View File

@@ -24,8 +24,6 @@ import org.redkale.mq.MessageConsumer;
@Repeatable(DynForMessaged.DynForMessageds.class)
public @interface DynForMessaged {
String dynField();
Class<? extends MessageConsumer> consumer();
@Inherited

View File

@@ -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<Integer> 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, "<init>", "(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<? extends MessageConsumer> 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<? extends MessageConsumer> 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;
}
}

View File

@@ -486,7 +486,7 @@ public abstract class Sncp {
* 创建Service的本地模式Class
*
* @param <T> 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<T>) (clz == null ? dynLoader.loadClass(newDynName.replace('/', '.')) : clz);
final String newDynClass = newDynName.replace('/', '.');
Class clz = RedkaleClassLoader.findDynClass(newDynClass);
return (Class<T>) (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不一致