2

BCEL を使用して、この方法で cglib 拡張オブジェクトのバイトコードを取得しようとしています。

package app;

import cglib.MyInterceptor;
import net.sf.cglib.proxy.Enhancer;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import service.Tool;

public class CgLibApp {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        // target object
        Tool tool = new Tool();

        // proxying
        Enhancer e = new Enhancer();
        e.setSuperclass(tool.getClass());
        e.setCallback(new MyInterceptor(tool));
        Tool proxifiedTool = (Tool) e.create();

        // trying to get proxy byte code
        JavaClass clazz = Repository.lookupClass(proxifiedTool.getClass());
        Method method = clazz.getMethod(Tool.class.getMethod("meth"));

        System.out.println(method.getCode().toString());
    }
}

しかし、私は得ています:

Exception in thread "main" java.lang.ClassNotFoundException: SyntheticRepository could not load service.Tool$$EnhancerByCGLIB$$22a3afcc
at org.apache.bcel.util.SyntheticRepository.loadClass(SyntheticRepository.java:174)
at org.apache.bcel.util.SyntheticRepository.loadClass(SyntheticRepository.java:158)
at org.apache.bcel.Repository.lookupClass(Repository.java:74)
at app.CgLibApp.main(CgLibApp.java:21)

Enhanced オブジェクトからバイトコードを取得するにはどうすればよいですか?

4

2 に答える 2

0

BCEL は、.classファイルを表すバイト配列を取得するために、クラス ローダーにファイルをクエリします。このようなクラス ファイルは、動的に生成されたクラスには存在しません。

クラス ファイルを取得するには、クラス ファイルの作成中にバイト コードを収集する必要があります。Cglib は ASM の上に構築されており、独自ClassVisitorの を登録してクラス ファイルを収集できます。

では、メソッドをEnhancer使用しgenerateClass(ClassVisitor)、後者のメソッドを a に渡しClassWriterます。メソッドを呼び出した後、渡したクラス ライター オブジェクトからバイト コードを取得できます。

于 2016-12-19T07:28:20.723 に答える
0

生成された CGLIB クラスの疑似コードを出力するサンプル コードを次に示します。 visitEndメソッドは、生成されたクラスをテキスト形式で出力します。

package naga.cglib.demo;

import static org.objectweb.asm.Opcodes.ASM7;

import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.TraceClassVisitor;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;

public class App {
public static void main(String[] args) throws Exception, IllegalArgumentException, InvocationTargetException {

    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(SampleClass.class);
    enhancer.setCallback(new FixedValueImpl());
    SampleClass proxy = (SampleClass) enhancer.create();
    enhancer.generateClass(new CustomClassWriter());

    System.out.println("Hello cglib!" + proxy.test(null));

}
}

class SampleClass {
public String test(String input) {
    return "Hello world!";
}
}

class FixedValueImpl implements FixedValue {

@Override
public Object loadObject() throws Exception {
    // TODO Auto-generated method stub
    return "Hello cglib! from loadObject()";
}

}

class CustomClassWriter extends ClassVisitor {

TraceClassVisitor tracer;
PrintWriter pw = new PrintWriter(System.out);

public CustomClassWriter() {
    super(ASM7);
    tracer = new TraceClassVisitor(pw);
}

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    System.out.println("method name is :" + name);
    return tracer.visitMethod(access, name, desc, signature, exceptions);

}

@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {

    System.out.println("field name is :" + name);
    return tracer.visitField(access, name, desc, signature, value);
}

public void visitEnd() {
    tracer.visitEnd();
    System.out.println(tracer.p.getText());

}
}
于 2020-05-07T14:24:52.190 に答える