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

    一、概念

    1、代理对象存在的价值主要用于拦截对真实业务对象的访问。
    2、代理对象应该具有和目标对象(真实业务对象)相同的方法。

    二、Java动态代理的实现

    1."java.lang.reflect.Proxy"类介绍

      要生成某一个对象的代理对象,这个代理对象通常也要编写一个类来生成,所以首先要编写用于生成代理对象的类。在java中如何用程序去生成一个对象的代理对象呢,java在JDK1.5之后提供了一个"java.lang.reflect.Proxy"类,通过"Proxy"类提供的一个newProxyInstance方法用来创建一个对象的代理对象。

    static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

    参数说明:

    ClassLoader loader用来指明生成代理对象使用哪个类装载器;
    Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定;
    InvocationHandler h用来指明产生的这个代理对象要做什么事情。

    2.编写生成代理对象的类

      在java中规定,要想生成一个对象的代理对象,那么这个对象必须要有一个接口。接口定义如下:

    package com.javaBase.Proxy;
    
    /**
     * 〈人接口〉;
     * 〈功能详细描述〉
     *
     * @author
     * @see [相关类/方法](可选)
     * @since [产品 /模块版本] (可选)
     */
    public interface PersonService {
    
        /**
         * 功能描述:
         * 〈吃饭〉
         *
         * @see [相关类/方法](可选)
         * @since [产品 /模块版本](可选)
         */
        public void eat();
    
        /**
         * 功能描述:
         * 〈睡觉〉
         *
         * @see [相关类/方法](可选)
         * @since [产品 /模块版本](可选)
         */
        public void sleep();
    }

    接口实现:

    package com.javaBase.Proxy;
    
    /**
     * 〈一句话功能简述〉;
     * 〈马云〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class MrMaImpl implements PersonService {
    
        @Override
        public void eat() {
            System.out.println("马云在吃饭...");
        }
    
        @Override
        public void sleep() {
            System.out.println("马云在打盹...");
        }
    }

    代理方法构建及测试代码:

    package com.javaBase.Proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 〈一句话功能简述〉;
     * 〈功能详细描述〉
     *
     * @author jxx
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class MrMaProxy {
    
        private PersonService mayun = new MrMaImpl();
    
        /**
         * 获取代理对象的方法
         * @return
         */
        public PersonService getProxy() {
            return (PersonService)Proxy.newProxyInstance(MrMaImpl.class.getClassLoader(), mayun.getClass().getInterfaces(), new InvocationHandler() {
                /**
                 *
                 * @param proxy 代理对象自己
                 * @param method 代理对象当前调用的方法
                 * @param args 方法参数
                 * @return
                 * @throws Throwable
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if("eat".equals(method.getName())) {
                        System.out.println("开始吃饭");
                        method.invoke(mayun,args);
                    } else if("sleep".equals(method.getName())) {
                        System.out.println("开始睡觉");
                        method.invoke(mayun,args);
                    }
                    return null;
                }
            });
        }
    
        public static void main(String[] args){
            MrMaProxy proxy = new MrMaProxy();
            PersonService ps = proxy.getProxy();
            ps.eat();
            ps.sleep();
        }
    }

    运行结果:

    开始吃饭
    马云在吃饭...
    开始睡觉
    马云在打盹...

    三、动态代理的应用

      在动态代理技术里,由于不管用户调用代理对象的什么方法,都是调用开发人员编写的处理器的invoke方法(这相当于invoke方法拦截到了代理对象的方法调用)。并且,开发人员通过invoke方法的参数,还可以在拦截的同时,知道用户调用的是什么方法,因此利用这两个特性,就可以实现一些特殊需求,例如:拦截用户的访问请求,以检查用户是否有访问权限、动态为某个对象添加额外的功能。实际应用如下:

    • Spring AOP的动态代理实现。Spring AOP的动态代理实现主要有两种方式,JDK动态代理和CGLIB字节码生成。默认情况下,如果Spring AOP发现目标对象后实现了相应的interface,则采用JDK动态代理机制为其生成代理对象。如果没有发现接口,则采用CGLIB的方式为目标对象生成动态的代理对象实例。
    • RPC框架中的应用。实际上RPC框架要解决的一个问题就是: 如何调用他人的远程服务?像调用本地服务一样调用远程服务。如何封装数据,通过网络传输给远程服务,使远程接口透明,这就需要动态代理的帮助了。所以透明化远程服务调用就是要利用动态代理,在代理层对数据进行封装,网络传输等操作。

    参考链接:Java动态代理实现及实际应用

         动态代理的原理及其应用

  • 相关阅读:
    读《程序是怎样跑起来的》第七章有感
    读《程序是怎样跑起来的》第六章有感
    读《程序是怎样跑起来的》第五章有感
    读《程序是怎样跑起来的》第四章有感
    读《程序是怎样跑起来的》第三章有感
    读《怎样成为一个高手 183》有感
    读《程序是怎样跑起来的》第二章有感
    《程序是怎样跑起来的》第一章读后感
    我与计算机
    师生关系
  • 原文地址:https://www.cnblogs.com/jxxblogs/p/12050944.html
Copyright © 2011-2022 走看看