静的プロキシと動的プロキシを理解する方法

はじめに:動的プロキシとは、リフレクションを介してプロキシクラスに基づいてプロキシクラスを作成し、プロキシクラスのメソッドを呼び出してリフレクションの動的な性質を反映することです。

静的プロキシの例:

特点:代理类和被代理类在编译期间,就确定下来了

静的プロキシモード:

package DynamicAgent;

/**
 * @Author:CT
 * @Date:2021/2/20
 * @Description:StaticAgent
 * @Version 1.0
 */

/*
    静态代理举例:
    特点:代理类和被代理类在编译期间,就确定下来了
 */

    interface ClothFactory{
    
    
        void produceClothes();
}

// 代理类
class Factory implements ClothFactory{
    
    
        private ClothFactory factory;
        Factory(ClothFactory f){
    
    
            this.factory=f;
        }

    public Factory() {
    
    

    }

    @Override
    public void produceClothes() {
    
    
        System.out.println("代理工厂做一些准备工作");
        factory.produceClothes();
        System.out.println("代理工厂做一些后续收尾工作");
    }
}

// 被代理类
 class Nike implements ClothFactory{
    
    

    @Override
    public void produceClothes() {
    
    
        System.out.println("耐克生产一批运动服");
    }
}

public class StaticAgentUse01 {
    
    
    public static void main(String[] args) {
    
    
        // 创建被代理类的对象  体现了多态性
        ClothFactory nike = new Nike();
        // 创建代理类的对象
        ClothFactory factory = new Factory(nike);
        // 调用方法
        factory.produceClothes();
    }
}

出力結果:

代理工厂做一些准备工作
耐克生产一批运动服
代理工厂做一些后续收尾工作

動的プロキシ(プロキシクラスは動的です):

解释: 动态代理就是为了调被代理类的方法 省去的是代理类的操作

動的エージェントを実装するために解決する必要がある問題:

①メモリにロードされたプロキシクラスに基づいてプロキシクラスとそのオブジェクトを動的に作成する
方法?プロキシクラスオブジェクトを介してメソッドを呼び出す場合、呼び出したいプロキシクラスの特定のメソッドを反映する方法

動的プロキシモード:

package DynamicAgent;



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author:CT
 * @Date:2021/2/20
 * @Description:DynamicAgent
 * @Version 1.0
 */
/*
    动态代理(代理类是动态的)
    解释: 动态代理就是为了调被代理类的方法 省去的是代理的操作

   实现动态代理需要解决的问题:
   ① 如何根据加载到内存中的被代理类,如何动态的创建的一个代理类及其对象
   ② 当通过代理类的对象调用方法时,如何体现想调的是被代理类的某个方法
 */

//接口
interface Human{
    
    
    String getBelief();
    void eat(String food);
}
// 被代理类
class Superman implements Human{
    
    

    @Override
    public String getBelief() {
    
    
        return "I Believe I can Win !";
    }

    @Override
    public void eat(String food) {
    
    
        System.out.println("我喜欢吃"+food);
    }
}

// 专门生成代理类
class ProxyFactory{
    
    
    // 调用此方法 返回一个代理类的对象 解决问题一
    public static Object getProxyInstance(Object obj)// obj 代表是被代理类的对象
    {
    
    
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
        myInvocationHandler.bind(obj);
      return   Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),myInvocationHandler);

    }
}

class MyInvocationHandler implements InvocationHandler{
    
    
    private Object obj;//赋值时也需要使用被代理类的对象
    public void bind(Object obj){
    
    
        this.obj=obj;

    }
    // 当我们通过代理类的对象,去调用a方法时,会自动的调用如下的方法: invoke()
    // 将被代理类要执行的方法a的功能 声明在invoke 方法中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
       // method 此方法即为代理类对象调用的方法,也是作为被代理类调用的方法
        //object : 被代理类的对象
        Object invoke = method.invoke(obj, args);
        //上述方法的返回值就是作为invoke 方法的返回值
        return invoke;
    }
}
public class DynamicAgentUse01 {
    
    
    public static void main(String[] args) {
    
    
        Superman superman=new Superman();
        Human proxyInstance = (Human)ProxyFactory.getProxyInstance(superman);
        String belief = proxyInstance.getBelief();
        System.out.println(belief);

        proxyInstance.eat("番茄");

        //测试
       Nike nike=new Nike();
        ClothFactory proxyInstance1 = (ClothFactory)ProxyFactory.getProxyInstance(nike);
        proxyInstance1.produceClothes();

    }

}

出力結果:

我喜欢吃番茄
耐克生产一批运动服

おすすめ

転載: blog.csdn.net/weixin_46351306/article/details/113926285