Loading

[设计模式]代理模式

代理模式PROXY

静态代理

定义一个代理规范,规定代理和目标对象实现同样的方法
举个例子,银行柜员和银行都要有取钱的方法,我们才能通过银行柜员去取银行的钱

public interface Proxy {
    void withdraw();
}

public class Bank implements Proxy{
    @Override
    public void withdraw(){
        System.out.println("银行正在为你取钱");
    }
}

public class Stuff implements Proxy{

    Bank bank;
    @Override
    public void withdraw() {
        if(bank == null){
            bank = new Bank();
        }

        System.out.println("银行柜员正在为你取钱");
        bank.withdraw();
        System.out.println("银行柜员取钱完成");

    }
}
public class User {
    public static void main(String[] args) {
        Stuff stuff = new Stuff();
        stuff.withdraw();
    }
}

动态代理

首先我们编写一个目标类,也就是真正干活的类

public class TrainStation implements ProxyMethod {
    public TrainStation() {
    }

    @Override
    public void sellTicket() {
        System.out.println("火车站正在出票");
    }

    @Override
    public boolean refund() {
        System.out.println("火车站正在退票");
        return true;
    }
}

然后定义一个接口,规定我们想要代理的方法


public interface ProxyMethod {

    void sellTicket();

    boolean refund();

}

编写代理工具类,负责生成代理对象

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

public class ProxyUtil {

    public static ProxyMethod creatProxy(TrainStation trainStation) {

        ProxyMethod proxyMethod = (ProxyMethod) Proxy.newProxyInstance(
            
                ProxyUtil.class.getClassLoader(),
                new Class[]{ProxyMethod.class},
                new InvocationHandler() {
                    @Override
                    // 当我们使用代理对象
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().equals("sellTicket")) {
                            System.out.println("代理正在买票");
                        }
                        if (method.getName().equals("refund")) {
                            System.out.println("代理正在退票");
                        }
                        
                        Object res = method.invoke(trainStation, args);

                        if (method.getName().equals("sellTicket")) {
                            System.out.println("代理正在出票");
                        }
                        if (method.getName().equals("refund")) {
                            System.out.println("代理正在退票");
                        }

                        return res;
                    }

                });
        return proxyMethod;

    }
}

最后client测试

public class Client {
    public static void main(String[] args) {
        TrainStation trainStation = new TrainStation();
        ProxyMethod p = ProxyUtil.creatProxy(trainStation);
        p.sellTicket();
        boolean b = p.refund();
        System.out.println(b);
    }
}

动态代理分为两种一种是jdk代理

JDK动态代理是Java标准库中提供的一种代理方式,它可以在运行时动态生成一个代理对象,代理对象实现和原始类一样的接口,并将方法调用转发给被代理对象,同时还可以在方法调用前后执行额外的增强处理。

JDK动态代理通过反射机制实现代理功能,其原理分为以下几个步骤:

创建实现InvocationHandler接口的代理类工厂:在调用Proxy类静态方法newProxyInstance时,会动态生成一个代理类。该代理类实现了目标接口,并且持有一个InvocationHandler类型的引用。
InvocationHandler接口:InvocationHandler是一个接口,它只有一个方法invoke。在代理对象的方法被调用时,JVM会自动调用代理类的invoke方法,并将被调用的方法名、参数等信息传递给该方法。
调用代理对象的方法:当代理对象的方法被调用时,JVM会自动调用代理类的invoke方法。在invoke方法中,可以根据需要执行各种逻辑,比如添加日志、性能统计、事务管理等。
invoke方法调用:在invoke方法中,通过反射机制调用目标对象的方法,并返回方法的返回值。在调用目标对象的方法前后,可以执行额外的逻辑。

posted @ 2024-07-06 21:06  Duancf  阅读(21)  评论(0)    收藏  举报