デザインモード-(エージェントモード)

エージェンシーモード:

         プロキシモードは、開閉の原理の実装でもあり、ソースコードを変更せずに機能が拡張され、ターゲットオブジェクトがプロキシオブジェクトによってカプセル化され、ターゲットオブジェクトが非表示になり、元のオブジェクトのプリセールスが実行されます。機能。アフターサービス;春のaopは典型的な代理店モデルです

         静的プロキシモード:

   

// 目标对象和代理对象实现同一个接口
interface Interface01{
    void fun01();
}
// 目标对象
class TargetClass implements Interface01{

    @Override
    public void fun01() {
        System.out.println("执行目标对象函数");
    }
}
// 代理对象
class ProxyClass implements Interface01{
   // 目标对象
    private TargetClass targetClass ;
   // 有参构造器(传入一个目标对象的实例)
    public ProxyClass(TargetClass targetClass) {
        this.targetClass = targetClass;
    }
    // 执行方法
    @Override
    public void fun01() {
        System.out.println("执行前***");
        targetClass.fun01();
        System.out.println("执行后***");
    }
}

   動的プロキシ:

        静的エージェントは毎回プロキシクラスを必要とするため、動的プロキシが表示され、プロキシクラスが動的に作成されます

      j'd'kでサポートされる動的プロキシ:jdkの動的プロキシはインターフェイスに基づいており、ターゲットクラスはインターフェイスを実装する必要がありますが、実際にはすべてのクラスにインターフェイスがあるわけではありません。

public class TestDynamicProxy {
    public static void main(String[] args) {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new TargetDncymicClass());
        // 获取代理对象
        Interface02 proxy = (Interface02) myInvocationHandler.getProxy();
        proxy.fun02();
    }
}
// 接口
interface  Interface02{
      void fun02();
}
// 目标类
class TargetDncymicClass implements Interface02{

    @Override
    public void fun02() {
        System.out.println("TargetDncymicClass...");
    }
}
// invocationHandler
class MyInvocationHandler implements InvocationHandler{
    private Object target;
    // 传入目标对象
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行前。。");
        // 执行目标方法
        Object object = method.invoke(target, args);
        System.out.println("执行后。。");
        return object;
    }
    // 获取生成的代理对象
    public Object getProxy() {
        // 参数1 类加载器,参数2 目标类的所有实现接口, 参数3 InvocationHandler
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }
}

Cglib:

   cglibによって実装される動的プロキシは、インターフェイスを実装するためにターゲットクラスを必要とせず、最下層はasmバイトコードを使用してプロキシクラスのバイトコードを生成します

// 定义目标类
class TargetCglibClass{
// 目标方法
    public void test() {
        System.out.println("TargetCglibClass...");
    }

// methodInterceptor 方法拦截器
class MyMethodInterceptor implements MethodInterceptor{

    @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 static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(TargetCglibClass.class);
        enhancer.setCallback(new MyMethodInterceptor());
        TargetCglibClass o = (TargetCglibClass) enhancer.create();
        o.test();
    }

 

jdkとcglibの動的プロキシ実装の違い


1.jdk動的プロキシによって生成されたプロキシクラスと委任クラスは同じインターフェイスを実装します。2。cglib動的プロキシで生成されたバイトコードはより複雑です。生成されたプロキシクラスは委任クラスのサブクラスであり、最終的なキーワードを処理できません。 。変更されたメソッド;
3。jdkはリフレクションメカニズムを使用してデリゲートクラスのメソッドを呼び出し、cglibはインデックスと同様のメソッドを使用してデリゲートクラスメソッドを直接呼び出します。

おすすめ

転載: blog.csdn.net/xiaodujava/article/details/88866292