バイトコード命令
do {
自动计算PC寄存器以及从PC寄存器的位置取出操作码;
if (存在操作数) 取出操作数;
执行操作码所定义的操作;
} while (处理下一次循环);
操作バイトコード
操作は、CGLIB、ASM、Javassistのように直接、オープンソースのライブラリのバイトコード、などを利用することができる、彼らはプログラムを実行することができ、バイトコードのクラスは、動的に既存のクラスのバイトコードを作成または編集します。ここで、ASM CGLIBは、ライブラリーを作製するための非常に効率的かつ効果的に達成基づき、コントラスト、Javassistのがはるかに簡単;およびASMライブラリは軽量ですが、JVMや操作指示を参加させる必要性それは完全にJavaベースのAPIですが、そのパフォーマンスが悪化する前の2と比較します。
動的プロキシを使用したCGLIB
Javaコンパイラは、実行時にプロキシクラスが、動的に生成されたプロキシクラスのバイトコードを生成し、メモリにロードされていない直後。それはJDKの動的プロキシインタフェースのInvocationHandlerを実装することによって達成することができますので、。
// 示例:JDK实现动态代理
public class ProxyHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Start");
Object o = method.invoke(this, args);
System.out.println("End");
return o;
}
}
使用JDKダイナミックプロキシクラスは、インターフェイスを実装する必要があり、実際の開発にいくつかの制限があり、反射効率が非常に高くないので、操作は、バイトコード技術動的プロキシを実装するために利用することができます。春は両方の方法を達成しながら、あなたが実際の開発ではJDKの動的プロキシに基づいて、または動的プロキシCGLIBに基づいて選択することができます人気の開発フレームワークです。
動的プロキシCGLIBの依存関係を導入する必要性と、ASMによって達成CGLIB
<!-- cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
<!-- asm -->
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
これは、エージェントクラスにする必要があります
// 需要被代理的类
public class HelloCGLib {
public HelloCGLib() {
System.out.println("HelloCGLib构造器");
}
public void sayHello(String name) {
System.out.println("HelloCGLib:" + name);
}
}
CGLIBインターセプタを達成する方法
// 实现CGLib的方法拦截器
public class ProxyInterceptor implements MethodInterceptor {
/**
* @param o cglib生成的代理对象
* @param method 被代理对象方法
* @param objects 方法入参
* @param methodProxy 代理方法
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("======前置通知======");
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("======后者通知======");
return object;
}
}
テストカテゴリ
public class Test {
public static void main(String[] args) {
// 代理类class文件存入本地磁盘方便我们反编译查看源码
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "F:\\");
// CGLIB 增强类
Enhancer enhancer = new Enhancer();
// 设置增强类对象的父类
enhancer.setSuperclass(HelloCGLib.class);
// 设置增强类的回调类
enhancer.setCallback(new ProxyInterceptor());
// 创建代理对象
HelloCGLib proxy = (HelloCGLib) enhancer.create();
// 通过代理对象调用目标方法
proxy.sayHello("hehe");
}
}
業績
HelloCGLib构造器
======前置通知======
HelloCGLib:hehe
======后者通知======
生成されたプロキシクラス下板F
CGLIBは、クラスのサブクラスによって生成されるので、強化する必要があり、エージェントが動的達成するための請求方法を覆って、薬剤はCGLIBフリーできるようにインタフェースクラスを直接、しかしエージェントは、最終的なクラスはありません。