zoukankan      html  css  js  c++  java
  • 动态代理

    时间:2017-1-4 22:33

    ——动态代理(Proxy)概述

    1、只学一个方法:
        Proxy proxy = newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

    2、方法的作用:
        在运行时动态创建一个实现了一组指定接口的对象。

    3、参数:
        1)ClassLoader:类加载器
            它是用来加载类的,把.class文件加载到内存,生成Class对象。

        2)Class[] interfaces:Class数组
            指定要实现的接口们。

        3)InvocationHandler:
            代理对象的所有方法(个别方法不执行,例如getClass())都会调用InvocationHandler的invoke()方法。

    4、动态代理的作用
        最终学习AOP(面向切面编程),它与装饰设计模式相似,但比装饰设计模式灵活。

    示例代码:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
     
    import org.junit.Test;
     
    public class Demo {
        @Test
        public void fun(){
     
            /*
             * 三大参数
             * 1、ClassLoader
             * 该方法会动态生成一个类,这个类实现了A、B接口,然后创建这个类的对象
             * 需要生成一个类,这个类也需要通过ClassLoader加载到方法区中
             * 
             * 2、Class[] interfaces
             * 它是要实现的接口们
             * 
             * 3、InvocationHandler
             * 它是调用处理器
             * 
             * 代理对象实现的所有接口中的方法内容都是调用InvocationHandler的invoke()方法
             */
            ClassLoader loader = this.getClass().getClassLoader();

     
            InvocationHandler h = new InvocationHandler(){
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("Hello Proxy");
                    return null;
                }
            };
     
            //使用三大参数创建代理对象
            Object o = Proxy.newProxyInstance(loader, new Class[]{A.class, B.class}, h);
     
            A a = (A)o;
            B b = (B)o;
     
            a.a();
            b.b();
        }
    }
     
    interface A{
        public Object a(String s, int i);
        public Object aa(String s, int i); 
    }
     
    interface B{
        public void b();
    }

    打印结果:
    Hello Proxy
    Hello Proxy
     




    ——InvocationHandler接口

    1、只有一个方法:
        public Object invoke(Object proxy, Method method, Object[] args);
        在调用代理对象所实现接口中的方法时被调用。

        *   Object proxy:当前对象,即代理对象。
        *   Method method:当前被调用的方法(目标方法)。
        *   Object[] args:实参。

    2、invoke()方法与代理对象调用方法的关系
        图片


    ——动态代理应用

    增强的方式:
        1、继承
            *   被增强对象不能变
            *   增强内容不能变
        2、装饰设计模式
            *   被增强对象可变
            *   增强内容不可变
        3、动态代理
            *   被增强对象可变
            *   增强内容可变

    目标对象:被增强的对象。
    代理对象:需要目标对象,然后在目标对象上添加了增强后的对象。
    目标方法:被增强的内容。

    代理对象 = 目标对象 + 增强内容

    =============================================================================
    示例代码:

    package com.wyc.demo2;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
     
    import org.junit.Test;
     
    public class Demo2 {
        @Test
        public void fun1() {
            // 目标对象
            Waiter manWaiter = new ManWaiter();
            /*
             * 给出三个参数,来创建方法,得到代理对象
             */
            ClassLoader loader = this.getClass().getClassLoader();
            Class[] interfaces = { Waiter.class };
     
            // manWaiter表示目标对象
            InvocationHandler h = new WaiterInvocationHandler(manWaiter);
     
            // 得到代理对象,其实代理对象就是在目标对象的基础上进行增强的对象
            Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(loader, interfaces, h);
     
            /*
             * 在服务方法前添加“你好”,在服务方法后添加“再见”
             */
            waiterProxy.serve();
        }
    }
     
    class WaiterInvocationHandler implements InvocationHandler {
        // 目标对象
        private Waiter waiter;
        public WaiterInvocationHandler(Waiter waiter){
            this.waiter = waiter;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("您好");
            // 调用目标对象的目标方法
            this.waiter.serve();
            System.out.println("再见");
            return null;
        }
    }

    ----------------------------------------------------------------------------------------------------------------------------

    package com.wyc.demo2;
     
    public interface Waiter {
        // 服务方法
        public void serve();
    }

    ----------------------------------------------------------------------------------------------------------------------------

    package com.wyc.demo2;
     
    public class ManWaiter implements Waiter {
        @Override
        public void serve() {
            System.out.println("服务中...");
        }
    }
    ============================================================================= 
     

    ——代理工厂实现

    ============================================================================= 


    ProxyFactory:

    package com.wyc.demo3;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
     
    /*
     * 代理工厂
     * 它用来(组装)生成代理对象
     * 所需参数:
     *  * 目标对象
     *  * 增强内容
     */
     
    /*
     * 1、创建代理工厂
     * 2、给工厂设置三个属性:
     *  * 目标对象:setTargetObject(xxx);
     *  * 前置增强对象:setBeforeAdvice(该接口的实现类)
     *  * 后置增强对象:setAfterAdvice(该接口的实现类)
     *  
     * 3、调用createProxy()方法得到代理对象
     *  * 执行代理对象方法时,首先执行的是BeforeAdvice的before()方法
     *  * 目标对象的目标方法
     *  * 最后会执行AfterAdvice的after()方法
     */
    public class ProxyFactory {
        // 目标对象
        private Object targetObject;
     
        // 前置增强对象
        private BeforeAdvice beforeAdvice;
     
        // 后置增强对象
        private AfterAdvice afterAdvice;
     
        /*
         * 用来生成代理对象
         */
        public Object createProxy(){
            /*
             * 1、给出三大参数
             */
            ClassLoader loader = this.getClass().getClassLoader();
            // 得到该对象的真实类型,获取该类型实现的所有接口
            Class[] interfaces = targetObject.getClass().getInterfaces();
            InvocationHandler h = new InvocationHandler(){
     
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    /*
                     * 在调用代理对象的方法时,会调用该方法,执行这里的内容
                     */
                    // 执行前置增强
                    if(beforeAdvice != null){
                        beforeAdvice.before();
                    }
     
                    // 通过反射得到的Method类,调用目标对象的目标方法
                    Object result = method.invoke(targetObject, args);
     
                    // 执行后置增强
                    if(afterAdvice != null){
                        afterAdvice.after();
                    }
     
                    // 返回目标对象的返回值
                    return result;
                }
            };
     
            /*
             * 2、得到代理对象
             */
            Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
            return proxyObject;
        }
     
        public Object getTargetObject() {
            return targetObject;
        }
     
        public void setTargetObject(Object targetObject) {
            this.targetObject = targetObject;
        }
     
        public BeforeAdvice getBeforeAdvice() {
            return beforeAdvice;
        }
     
        public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
            this.beforeAdvice = beforeAdvice;
        }
     
        public AfterAdvice getAfterAdvice() {
            return afterAdvice;
        }
     
        public void setAfterAdvice(AfterAdvice afterAdvice) {
            this.afterAdvice = afterAdvice;
        }
    }
    ----------------------------------------------------------------------------------------------------------------------------

    测试:

    package com.wyc.demo3;
     
    import org.junit.Test;
     
    /*
     * 让目标对象和增强内容都可以切换
     * 不决定增强对象和增强内容,只起到了装配作用
     */
    public class Demo3 {
        @Test
        public void fun() {
            // 创建工厂
            ProxyFactory factory = new ProxyFactory();
     
            // 设置目标对象
            factory.setTargetObject(new ManWaiter());
     
            // 设置前置增强对象
            factory.setBeforeAdvice(new BeforeAdvice() {
     
                @Override
                public void before() {
                    System.out.println("您好");
                }
            });
     
            // 设置后置增强对象
            factory.setAfterAdvice(new AfterAdvice() {
     
                @Override
                public void after() {
                    System.out.println("再见");
                }
            });
     
            Waiter waiter = (Waiter) factory.createProxy();
            waiter.serve();
            waiter.money();
        }
    }
    ----------------------------------------------------------------------------------------------------------------------------

    Waiter接口:

    package com.wyc.demo3;
     
    public interface Waiter {
        // 服务方法
        public void serve();
     
        // 增加方法
        public void money();
    }
    ----------------------------------------------------------------------------------------------------------------------------

    ManWaiter接口:

    package com.wyc.demo3;
     
    public class ManWaiter implements Waiter {
     
        @Override
        public void serve() {
            System.out.println("服务中...");
        }
     
        @Override
        public void money() {
            System.out.println("收钱...");
        }
    }

    ----------------------------------------------------------------------------------------------------------------------------

    BeforeAdvice接口:

    package com.wyc.demo3;
     
    /*
     * 前置增强
     */
    public interface BeforeAdvice {
        public void before();
    }

    ----------------------------------------------------------------------------------------------------------------------------
     

    AfterAdvice接口:

    package com.wyc.demo3;
     
    /*
     * 后置增强
     */
    public interface AfterAdvice {
        public void after();
    }
  • 相关阅读:
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
  • 原文地址:https://www.cnblogs.com/wwwwyc/p/6375386.html
Copyright © 2011-2022 走看看