• 反射与代理设计模式


    如果要想动态的创建代理对象,那么就需要使用一个java.lang.reflect.Proxy程序类,在这个类中提供有一个动态实例化新的代理对象的操作方法:

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

    在本方法之中参数的作用如下:

    · ClassLoader loader:类加载器,确定代理对象的产生使用的类加载器是什么;

    · Class<?>[] interfaces:要代理类所实现的接口;

    · InvocationHandler h:实现了代理调用的处理;

    如果要想实现整个动态代理操作,那么核心的关键除了Proxy类之外,还有一个InvocationHandler接口,那么这个接口定义如下:

    public interface InvocationHandler{
        /*
         * 动态代理设计模式之中的代理处理方法
         * @param proxy 代理对象
         * @param method 真实主题要调用的方法,结合本类的真实对象可以反射调用方法(真实主题)
         * @param args 表示执行方法时所需要的参数
         * @return  Method 对象反射调用真实主题方法
         * @throws Throwable
         */
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
    }

    实现动态代理:

     1 package cn.test;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.lang.reflect.Proxy;
     6 
     7 interface ISubject{
     8     public void get();
     9 }
    10 class RealISubject implements ISubject{
    11     public void get(){
    12         System.out.println("吃饭");
    13     }
    14 }
    15 
    16 class ProxyImpl implements InvocationHandler{
    17     private Object real;
    18     /**
    19      * 如果要想通过动态代理实现类操作invoke()方法,那么必须创建动态对象,同时要保存被代理对象
    20      * 如果要想动态创建代理对象,那么必须首先要知道真实对象
    21      * @param obj 要代理的真实对象
    22      * @return proxy 动态创建的代理对象
    23      *
    24      */
    25     public Object bin(Object obj){
    26         this.real = obj;//保存真实对象
    27         return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    28     }
    29     public void prepare(){
    30         System.out.println("餐厅人员准备食物");
    31     }
    32     public void after(){
    33         System.out.println("餐厅人员清理餐桌");
    34     }
    35     public Object invoke(Object proxy,Method method, Object[] args) throws Throwable{
    36         this.prepare();
    37         Object ret = method.invoke(this.real, args); //调用真实方法
    38         this.after();
    39         return ret;
    40     }
    41 }
    42 public class TestLocal{
    43     public static void main(String[] args) {
    44         ISubject subject = (ISubject) new ProxyImpl().bin(new RealISubject());
    45         subject.get();
    46     }
    47 }

    结果:

    餐厅人员准备食物
    chifan
    餐厅人员清理餐桌

    总结:此时的Proxy的代理类不会再局限于某一个特定的接口对象操作,而是可以直接进行所有接口子类对象的代理操作,这就是动态代理设计模式的雏形。

  • 相关阅读:
    一个asp.net MVC 的分页代码
    JavaScript教程:JavaScript如何判定用户浏览器类型和版本号?
    CutyCapt A Qt WebKit Web Page Rendering Capture Utility
    Top 10 Algorithms in Data Mining
    a c++ bloger
    设置MYSQL允许用IP访问
    QtWebKit Module
    kubuntudesktop nearly 700m,so big
    Wt, C++ Web Toolkit Introduction
    硅谷、纽约、伦敦如何演绎世界三大科技中心
  • 原文地址:https://www.cnblogs.com/liyang31/p/5822269.html
Copyright © 2020-2023  润新知