设计模式之动态代理模式

学习动态代理模式是为了以后学习AOP(面向切面编程)打下基础,他比装饰者模式还要灵活。

我们只学习他的一个方法:

Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler invocationHandler);

作用:在运行时,动态创建一组指定的接口的实现类对象。

三个参数分别是:

1. ClassLoader classLoader:类加载器,把.class文件加载到JVM的方法区,变成class对象

2.Class[] interfaces:指定要实现的接口

3.InvocationHandler invocationHandler:调用处理器,这是个接口

查看API得知有一个方法:
public Object invoke(Object proxy, Method method, Object[] args);

interface A {
    void a();
    Object aa(String x);
   
}

interface B {
    void b();
}

public class Demo1 {
    public static void main(String[] args) {       
    donttai();
    }

    private static void donttai() {
        //通过目标对象得到类加载器
     Demo1 d=new Demo1(); ClassLoader classLoader = d.getClass().getClassLoader(); InvocationHandler invocationHandler = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("动态代理有点难"); return "aaa"; } }; //使用三大参数创建代理对象 Object o = Proxy.newProxyInstance(classLoader, new Class[]{A.class, B.class}, invocationHandler); A a = (A) o; B b = (B) o; a.a(); b.b(); 输出:动态代理有点难 动态代理有点难 a被传递给了proxy这个参数,aa传递给了method参数,括号中的内容传递给了args1 Object aaa = a.aa("hello"); System.out.println(aaa); 输出:动态代理有点难 由此可得:代理对象实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法

例子

public interface Waiter {
    //这个waiter可以服务别人
    void service();
}

public class ManWaiter implements Waiter {

    public void service() {
        System.out.println("服务周到");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        getOne();
    }

    private static void getOne() {
        //manWaiter就是一个目标对象(需要被增强的)
        Waiter manWaiter = new ManWaiter();
        //通过目标对象得到类加载器
        ClassLoader classLoader = manWaiter.getClass().getClassLoader();
     //需要被实现的接口 Class[] interfaces
= new Class[]{Waiter.class}; InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("你好"); manWaiter.service(); System.out.println("再见"); return null; } }; //得到一个代理对象,代理对象就是在目标对象的基础上进行增强的对象 Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); //在调用代理对象的时候,在前面添加“你好”,后面添加“再见”, //因为需要一个目标对象,所以需要自己传一个 waiterProxy.service(); } } 输出: 你好 服务周到 再见

 也可以创建一个代理工厂类,来提高程序的可读性

interface After {
    public void after();
}

interface Before {
    public void before();
}

public class ProxyFactory {
    private Object target;//目标对象
    private Before before;//前置增强
    private After after;//后置增强

    Object createProxy() {
        //得到类加载器对象
        ClassLoader loader = this.getClass().getClassLoader();
        //得到接口
        Class[] interfaces = target.getClass().getInterfaces();
        InvocationHandler h = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                // 执行前置增强
                if (before != null) {
                    before.before();
                }
                //通过反射得到目标对象调用的方法
                Object result = method.invoke(target, args);//执行目标对象的目标方法
                // 执行后置增强
                if (after != null) {
                    after.after();
                }

                // 返回目标对象的返回值
                return result;
            }
        };
        //得到代理对象
        Object proxyObject;
        proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
        return proxyObject;
    }


    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public Before getBefore() {
        return before;
    }

    public void setBefore(Before before) {
        this.before = before;
    }

    public After getAfter() {
        return after;
    }

    public void setAfter(After after) {
        this.after = after;
    }
}
public class Demo2 {
    public static void main(String[] args) {
        //创建工厂
        ProxyFactory proxyFactory=new ProxyFactory();
        //创建目标对象
        proxyFactory.setTarget(new ManWaiter());
        //创建前置对象
        proxyFactory.setBefore(new Before() {
            @Override
            public void before() {
                System.out.println("你好");
            }
        });
        //创建后置对象
        proxyFactory.setAfter(new After() {
            @Override
            public void after() {
                System.out.println("再见");
            }
        });
        //通过代理对象
        Waiter waiter = (Waiter) proxyFactory.createProxy();
        waiter.service();
    }
}

输出:
你好
服务周到
再见

 

posted @ 2018-08-12 11:30  奥克兰毛泽西  阅读(84)  评论(0编辑  收藏  举报