Proxy代理模式

定义:代理一个对象,去执行对象的方法。

使用场景:根据开闭原则,很多时候我们不能去直接修改被代理的实现类,而又要增加业务逻辑,这时可以使用代理模式。

举例:比如我们调用一个第三方接口的方法,现在有个新需求,在执行某个方法前,需要记录日志,我们无法修改第三方接口,这时可以使用代理模式。

优点:程序扩展性、可维护性增强,无需更改以前的实现。

1.  静态代理

对每一个需要被代理的类,新增一个代理类;

1.1 支付接口

public interface PayService {

    void pay();

}

1.2 被代理对象,实现支付接口

public class PayServiceImpl implements PayService{

    @Override

    public void pay() {

        System.out.println("支付完成");

    }

}

1.3 代理类,实现支付接口

public class StaticProxy implements PayService{

    private PayService payService;

    public StaticProxy(PayService payService) {

        this.payService = payService;

    }

    @Override

    public void pay() {

        System.out.println("支付日志记录...");

        payService.pay();

    }

}

1.4 调用示例:

public class StaticProxyMain {

    public static void main(String[] args) {

        PayService payService = new PayServiceImpl();

        StaticProxy proxy = new StaticProxy(payService);

        proxy.pay();

    }

}

打印结果如下:

支付日志记录...

支付完成

2.动态代理

采用InvocationHandler实现,InvocationHandler是一个JDK提供的标准接口。在动态代理实现时,无需指定被代理的类,在具体调用时再指定。

2.1 重写代理类

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class DynamicProxy implements InvocationHandler{

    private Object obj;

    public DynamicProxy(Object obj) {

        this.obj = obj;

    }

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object result = method.invoke(this.obj, args);

        return result;

    }

}

2.2 调用示例

import java.lang.reflect.Proxy;

public class DynamicProxyMain {

    public static void main(String[] args) {

        PayService payService = new PayServiceImpl();

        DynamicProxy proxy = new DynamicProxy(new PayServiceImpl());

        PayService payServiceProxy = (PayService) Proxy.newProxyInstance(payService.getClass().getClassLoader(),                    payService.getClass().getInterfaces(), proxy);

        System.out.println("支付日志记录...");

        payServiceProxy.pay();

    }

}

打印结果和上面是一致的. 下面这段代码返回PayService,但并不是PayServiceImpl的实例,而是JVM给我们加过工的,包含了我们在invoke方法里的实现。debug,payServiceProxy类型为$Proxy0

PayService payServiceProxy = (PayService) Proxy.newProxyInstance(payService.getClass().getClassLoader(), payService.getClass().getInterfaces(), proxy);

你可能感兴趣的:(Proxy代理模式)