Java设计模式Java

代理模式-ProxyPattern

2018-05-12  本文已影响7人  Java酸不酸
前言:
代理模式与装饰者模式:
    相同点:
        1. 前提条件:装饰者(代理者)与被装饰者(委托者)要继承相同的父类或实现相同的接口。
        2. 都可以增强某个类的方法,对程序进行扩展。
    不同点:
        1. 代理者是为某个对象添加一个代理,以控制对这个对象的访问。而装饰者增强某个类的方法。
        2. 代理可以在调用核心方法之前做前置处理,在调用核心方法之后做后置处理。
代理模式
   定义:
    1. 为对象提供一种代理,加以控制对象的访问。
    2. 在某些特定的情况下一个对象不适合或者不能直接引用另一个对象,
       而代理对象可以在目标对象与客户直接起到中介作用。

代理模式的组成部分

静态代理

动态代理

定义

动态代理常用类详解

java.lang.reflect.Proxy
这是 Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理对象。

    public static Object newProxyInstance(ClassLoader loader, 
                                   Class<?>[] interfaces, InvocationHandler h)
    loader:指定类的装载器
    Interfaces:一组接口,委托类实现的所有接口
    H:处理器生成代理类实例
    @return:返回一个代理对象

java.lang.reflect.InvocationHandler
这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。每次生成动态代理类对象时都要指定一个对应的调用处理器对象。

    public Object invoke(Object proxy, Method method, Object[] args)
    proxy:动态创建的代理者实例, 一般不要调用, 会发生递归
    method:代理对象当前所调用的方法, 只要代理调用任何方法都会走到invoke方法
    args:参数列表
    @return:返回当前被调用方法的返回值

java.lang.ClassLoader

ClassLoader loader = jay.getClass().getClassLoader();

Dynamic Proxy Example

public interface Star {
    // 发布会
    public void conference();
    // 代言广告
    public void endorsementAD();
}
public class JayStar implements Star{
    @Override
    public void conference() {
        System.out.println("周杰棍正在开发布会.....");
    }

    @Override
    public void endorsementAD() {
        System.out.println("周杰棍正在帮百雀羚打广告.....");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Client {
    
    public static void main(String[] args) {
        // 实例化一个JayStar对象
        JayStar jay = new JayStar();
        // 获取字节码文件对象
        Class<? extends JayStar> clazz = jay.getClass();
        // 获取当前类的类加载器
        ClassLoader loader = Client.class.getClassLoader();
        // 委托者所实现的所有接口
        Class<?>[] interfaces = clazz.getInterfaces();
        /**
         * newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
         * loader:指定的类加载器
         * interfaces:委托者所实现的所有接口
         * h:处理器回调,动态设置代理
         */
        Star star = (Star) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
            // 动态代理的前置处理
            private void will() {
                System.out.println("发布会开始了。。。。");
            }
            // 动态代理的后置处理
            private void end() {
                System.out.println("发布会结束了。。。。");
            }
            /**
             * Object invoke(Object proxy, Method method, Object[] args)
             * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
             * proxy:第一个proxy指的是生成的动态代理对象
             * method:被调用的方法
             * args:调用该方法传入的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String name = method.getName();
                if (name.equals("fbh")) {
                    will();
                    jay.conference();
                    end();
                }
                if (name.equals("ad")) {
                    jay.endorsementAD();
                }
                return null;
            }
        });
        star.conference();
        star.endorsementAD();
    }
}

上一篇 下一篇

猜你喜欢

热点阅读