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

     
    1、前言
     
           写动态代理的代码涉及了一个非常重要的类 Proxy,通过Proxy的静态方法newProxyInstance才会动态创建代理对象。
     
    2、newProxyInstance方法
     
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
     
    三个参数分别表示: loader表示类加载器, interfaces表示代码要用来代理的接口 , h表示一个 InvocationHandler 对象,前面两个参数容易理解,
    最后一个InvocationHandler是什么?
     
    InvocationHandler是一个接口,官方文档解释说,每个代理的实例都有一个与之关联的 InvocationHandler 实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的 InvocationHandler 实现类,由它决定处理。
     
    public interface InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
    }
    
    InvocationHandler 内部只有一个 invoke() 方法,正是这个方法决定了怎么样处理代理传递过来的方法调用。其中参数proxy表示代理对象,method表示代理对象调用的方法,args表示调用的方法中的参数。所以Proxy动态产生的代理会调用InvocationHandler实现类,所以InvocationHandler才是实际执行者。
     
    3、代码实例
     
    //抽象主题
    interface AbstractSubject
    {
        void request();
    }
    //真实主题
    class RealSubject implements AbstractSubject
    {
        public void request()
        {
            System.out.println("访问真实主题方法...");
        }
    }
    //真实主题
    class RealSubject1 implements AbstractSubject
    {
        public void request()
        {
            System.out.println("访问真实主题方法1...");
        }
    }
    //动态代理类
    class DynamicProxy implements InvocationHandler {
        private Object object;
        public DynamicProxy(Object object) {
            this.object = object;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            Object result = method.invoke(object, args);
            after();
            return result;
        }
        private void before() {
            System.out.println("hello!");
        }
        private void after() {
            System.out.println("bye!");
        }
    }
    //测试类
    public class TestDynamicProxyPattern {
        public static void main(String[] args) {
            AbstractSubject abstractSubject = new RealSubject();
            DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject);
            Proxy.newProxyInstance(abstractSubject.getClass().getClassLoader(), abstractSubject.getClass().getInterfaces() , dynamicProxy);
            abstractProxy.request();
        }
    }
          
           上述动态代理只需要传入需要被代理类的对象(DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject)),然后调用Proxy类的工厂方法newProxyInstance去动态地创建一个代理类,最后调用代理类的方法便实现了“增强功能”。使用了动态代理之后,无论有多少类多少方法需要增加逻辑,只需要在使用的时候将类对象传入得到代理对象,然后使用代理对象调用需要增强的方法即可。
           所以这时候如果增加一个实现抽象主题的真是主题类,比如说叫做RealSubject1,这个时候只要只要把该类的对象传入动态代理类DynamicProxy中,通过接口又可以实现接口AbstractSubject的实现类。
     
    这样来实现:
    AbstractSubject abstractSubject1 = new RealSubject1();
    DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject1);
     
    4、总结
     
    1、区别于静态代理的生成代理类,动态代理的代理类通过 Proxy.newInstance() 方法生成。静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。
    2、不管是静态代理还是动态代理,代理与被代理者都要实现接口,还是要是面向接口编程,目的都是增强现有功能。
    3、动态代理通过 Proxy 动态生成 proxy class,但是它也指定了一个 InvocationHandler 的实现类。
    4、动态代理也有缺陷,它要求需要代理的对象必须实现了某个接口,而且也不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。
     
     
     
     
     
     
     
  • 相关阅读:
    使用CSS3 will-change提高页面滚动、动画等渲染性能----------------------------引用
    JavaScript 中 console 的用法 -------------------引用
    Babel 转译 class 过程窥探--------引用
    对JS继承的研究--------------引用
    对React的研究-------------引用
    matplotlib绘制子图
    matplotlib颜色线条及绘制直线
    matplotlib示例
    爬虫流程(前面发过的文章的合集)巩固
    菜鸟教程的 mysql-connector 基础
  • 原文地址:https://www.cnblogs.com/liujiarui/p/12408732.html
Copyright © 2011-2022 走看看