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

    动态代理有关的有两个类 
    1.interface InvocationHandler 
    Object invoke(Object proxy, Method method, Object[] args) 
    只这一个方法,后面再说 

    2.class Proxy 
    真正表示动态代理的类,提供两个静态方法: 

    Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) 
    用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”, 
    用来冒充真实的对象。 

    Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
    产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类), 
    它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法, 
    invoke方法就是我们用来做N多事情的地方 -_-。 

    --------------------分隔线----------------------------- 

    看完上面的代码,大致明白动态代理的含义: 
    A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做; 
    我声明产生B类的代理类B',由它来冒充B类的“兄弟”并“实现”A接口, 
    对外界来说B'应该也有c方法,可当真正调用它的时候, 
    它会去执行与它关联InvocationHandler的invoke()方法, 
    在这个方法里面你可以做很多事情。这样,这个请求就被“代理”到其它地方去了。 

    下面是根据我的理解画的一个说明图 
     


    --------------------分隔线----------------------------- 

    真实的接口: 

    public interface Hello {
    
        void sayHello(String to);
      
        void print(String p); 
     
    }

    它的真实实现类: 

    public class HelloImpl implements Hello {
        
        public void sayHello(String to) {
            System.out.println("Say hello to " + to);
        }
        
        public void print(String s) {
            System.out.println("print : " + s);
        }
        
    }

    在这里生成与代理类相关联的InvocationHandler对象 

    public class LogHandler implements InvocationHandler {
        
        private Object dele;
        
        public LogHandler(Object obj) {
            this.dele = obj;
        }
        
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            doBefore();
            //在这里完全可以把下面这句注释掉,而做一些其它的事情
            Object result = method.invoke(dele, args);
            after();
            return result;
        }
        
        private void doBefore() {
            System.out.println("before....");
        }
        
        private void after() {
            System.out.println("after....");
        }
    }

    最后是测试类: 

    public class ProxyTest {
    
        public static void main(String[] args) {
            HelloImpl impl = new HelloImpl();
            LogHandler handler = new LogHandler(impl);
            //这里把handler与impl新生成的代理类相关联
            Hello hello = (Hello) Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler);
            
            //这里无论访问哪个方法,都是会把请求转发到handler.invoke
            hello.print("All the test");
            hello.sayHello("Denny");
        }
    
    }

    这里是输出结果: 

    before....
    print : All the test
    after....
    before....
    Say hello to Denny
    after....

    1.什么是动态代理? 
    一种用于转发请求,进行特殊处理的机制,“动态”应该指的是“运行期”。 
    2.为什么使用动态代理? 
    可以对请求进行任何处理(如事务,日志等,这都是网上说的,我当然可以做任何处理) 
    3.使用它有哪些好处? 
    如上 
    4.哪些地方需要动态代理? 
    不允许直接访问某些类;对访问要做特殊处理等,我只能想到这些。
     

    转自:http://langyu.iteye.com/blog/410071

  • 相关阅读:
    使用golang访问kubebernetes
    使用 Rancher 管理现有 Kubernetes 集群
    Running powershell scripts during nuget package installation and removal
    How to Create, Use, and Debug .NET application Crash Dumps in 2019
    寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
    Selenium+Java之解决org.openqa.selenium.InvalidArgumentException: invalid argument报错问题
    Selenium环境搭建
    关于Xpath定位方法知道这些基本够用
    Web自动化之浏览器启动
    【翻译】编写代码注释的最佳实践
  • 原文地址:https://www.cnblogs.com/Venom/p/3294295.html
Copyright © 2011-2022 走看看