java中的动态代理机制

  在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。下面通过代码来学习java中的动态代理技术.

  首先定义一个接口:

package com.aop.spring;

/**
 * Created by xinfengyao on 16-2-29.
 */
public interface Perform {
    public void play();
}

  实现该接口:

package com.aop.spring;

/**
 * Created by xinfengyao on 16-2-29.
 */
public class Actor implements Perform {
    @Override
    public void play() {
        System.out.println("开始表演");
    }
}

  实现InvocationHandler:

package com.aop.spring;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Created by xinfengyao on 16-2-29.
 */
public class MyHandler implements InvocationHandler {  // 这个就是我们想要代理的真实对象
    Perform performer;
    public MyHandler(Perform performer) {
        this.performer = performer;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {     // 在代理的真实对象执行操作前, 我们可以执行自己的操作
        System.out.println("表演开始之前,开灯");          // 真实对象执行操作
        Object object = method.invoke(performer, args);

     //在真实对象执行完操作后, 我们也可以加上我们自己的操作
        System.out.println("表演结束, 关灯");
        return object;
    }
}

  创建代理,调用方法:

package com.aop.spring;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Created by xinfengyao on 16-2-29.
 */
public class ProxyDemo {
    public static void main(String[] args) {
        Perform performer = new Actor();

        InvocationHandler handler = new MyHandler(performer);
        Perform proxy = (Perform) Proxy.newProxyInstance(performer.getClass().getClassLoader(), performer.getClass().getInterfaces(), handler);
        proxy.play();

    }
}

运行结果:

表演开始之前,开灯
开始表演
表演结束, 关灯

  首先需要创建委托类对象,也就是我们想要代理的对象, 例如实例中的performer,  将其以构造函数传入代理处理器,代理处理器ProxyHandler中会以Java反射方式调用该委托类对应的方法。然后使用 Java反射机制中的Proxy.newProxyInstance方式创建一个代理类实例,创建该实例需要指定该实例的类加载器,需要实现的接口(即目 标接口),以及处理代理实例接口调用的处理器。

  最后,调用代理类目标接口方法时,会自动将其转发到代理处理器中的invoke方法内,invoke方法内部实现预处理,对委托类方法调用,事后处理等逻辑。

最新文章

  1. JavaScript高级程序设计学习笔记--DOM
  2. javascript中对象学习
  3. mysql中,主键与普通索引
  4. python之路-Day1
  5. HDFS 原理、架构与特性介绍--转载
  6. 多线程编程之Linux环境下的多线程(三)
  7. 简单linux块设备驱动程序
  8. shell编程技术之-基础知识
  9. linux高级编程
  10. python d:\test.py File "<stdin>", line 1 python d:\test.py ^ SyntaxError: invalid syntax
  11. JS、CSS中的相对路径
  12. [转]Linux 基本操作(RM 删除)
  13. 把玩Alpine linux(一):安装
  14. android-UI组件(四):AdapterView及其子类
  15. Day6-------------ext4文件系统
  16. Spark Scheduler内部原理剖析
  17. CSS(一)属性--border边框
  18. 【Linux系统编程应用】Linux音频编程基础(一)【转】
  19. UVA-1579 Matryoshka (区间DP)
  20. window.postMessage跨文档通信

热门文章

  1. 使用Mac的AppleScritp调用控制台的方式
  2. POJ 3243 Clever Y(离散对数-拓展小步大步算法)
  3. struts_22_xwork校验器列表使用说明
  4. Fresco源码解析 - DataSource怎样存储数据
  5. haskell笔记2
  6. libsvm
  7. C#语言基础2016/3/6
  8. 四则运算GUI版本功能展现
  9. SQL SERVER 2008 R2配置管理器出现“远程过程调用失败”【0x800706be】的解决办法
  10. 衣明志是个SB