MessageAsmMethodBoost优化
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 + ");");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.redkale.mq.MessageConsumer;
|
||||
@Repeatable(DynForMessaged.DynForMessageds.class)
|
||||
public @interface DynForMessaged {
|
||||
|
||||
String dynField();
|
||||
|
||||
Class<? extends MessageConsumer> consumer();
|
||||
|
||||
@Inherited
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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不一致
|
||||
|
||||
Reference in New Issue
Block a user