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

    JDK动态代理

    Java动态代理类位于Java.lang.reflect包下。

    主要涉及到以下两个类:

    1、 java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现

    该接口中仅定义了一个方法 Object invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

    2、java.lang.reflect.Proxy:生成动态代理类和对象对真实角色的代理访问。

    每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。

    该类即为动态代理类,其中主要包含以下内容:

    Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。

    Static Class getProxyClass(ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

    Static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

    什么是Dynamic Proxy?

    所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。在使用动态代理类时,我们必须实现InvocationHandler接口

    示例:

    接口:Subject.java

    public interface Subject {
        public int sellBooks();
    
        public String speak();
    }

    真实对象:RealSubject.java

    public class RealSubject implements Subject{
        @Override
        public int sellBooks() {
            System.out.println("卖书");
            return 1 ;
        }
    
        @Override
        public String speak() {
            System.out.println("说话");
            return "张三";
        }
    }

    处理器对象:MyInvocationHandler.java

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
     * 定义一个处理器*/
    public class MyInvocationHandler implements InvocationHandler {
        /**
         * 因为需要处理真实角色,所以要把真实角色传进来
         */
        Subject realSubject ;
    
        public MyInvocationHandler(Subject realSubject) {
            this.realSubject = realSubject;
        }
    
        /**
         *
         * @param proxy    代理类
         * @param method    正在调用的方法
         * @param args      方法的参数
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("调用代理类");
            if(method.getName().equals("sellBooks")){
                int invoke = (int)method.invoke(realSubject, args);
                System.out.println("调用的是卖书的方法");
                return invoke ;
            }else {
                String string = (String) method.invoke(realSubject,args) ;
                System.out.println("调用的是说话的方法");
                return  string ;
            }
        }
    }

    调用端:Main.java

    import java.lang.reflect.Proxy;
    
    /**
     * 调用类*/
    public class Client {
        public static void main(String[] args) {
            //真实对象
            Subject realSubject =  new RealSubject();
    
            MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject);
            //代理对象
            Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, myInvocationHandler);
    
            proxyClass.sellBooks();
    
            proxyClass.speak();
        }
    }

    参考:大话设计模式:面向对象程序设计23种常见设计模式通俗演义 11

    代理模式-https://www.runoob.com/design-pattern/proxy-pattern.html

  • 相关阅读:
    2019MCN网红新营销峰会于7月在上海开幕!
    2019以太坊开发者及应用峰会(北京)
    2019产品经理大会成都站将于6月正式起航!
    2019全球智慧零售大会将于5月30-31在厦门召开!
    2019全国融媒短视频峰会厦门站将于5月正式起航!
    2019创新中国春季峰会暨企业创新峰会于5月22-23日在上海召开!
    2019第四届新媒体千人峰会广州站将于6月正式开幕!
    DAMS2019中国数据智能管理峰会将于7月在上海召开!
    CSDI2019summit中国软件研发管理行业技术峰会深圳站来袭!
    JavaScript学习(六)
  • 原文地址:https://www.cnblogs.com/ooo0/p/12176518.html
Copyright © 2011-2022 走看看