当前位置:  编程技术>java/j2ee

Java动态代理的应用详解

    来源: 互联网  发布时间:2014-10-24

    本文导语:  动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组);然后再利用您指定的classloader将 class byte加载进系统,最后...

动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组);然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现你所有的接口的Proxy对象。请看实例分析:

代码如下:

package com.fans.common.proxy;

public interface BusinessProcessor {
  public void processBusiness();
}


代码如下:

package com.fans.common.proxy;
/**
 * 业务处理类
 * @author fanshadoop
 *
 */
public class BusinessProcessorImpl implements BusinessProcessor {

 @Override
 public void processBusiness() {
  System.out.println("processing business.....");

 }

}


代码如下:

package com.fans.common.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 业务代理类
 * @author fanshadoop
 *
 */
public class BusinessProcessorHandler implements InvocationHandler {

 private Object target = null;

 BusinessProcessorHandler(Object target) {
  this.target = target;
 }

 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  System.out
    .println("You can do something here before process your business");
  Object result = method.invoke(target, args);
  System.out
    .println("You can do something here after process your business");
  return result;
 }

}


代码如下:

package com.fans.common.proxy;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

public class Test {

 /**
  * @param args
  */
 public static void main(String[] args) {
  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
  BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
    bpimpl.getClass().getClassLoader(), bpimpl.getClass()
      .getInterfaces(), handler);
  bp.processBusiness();

  System.out.println(bp.getClass().getName());
  printClassDefinition(bp.getClass());
 }

 public static String getModifier(int modifier) {
  String result = "";
  switch (modifier) {
  case Modifier.PRIVATE:
   result = "private";
  case Modifier.PUBLIC:
   result = "public";
  case Modifier.PROTECTED:
   result = "protected";
  case Modifier.ABSTRACT:
   result = "abstract";
  case Modifier.FINAL:
   result = "final";
  case Modifier.NATIVE:
   result = "native";
  case Modifier.STATIC:
   result = "static";
  case Modifier.SYNCHRONIZED:
   result = "synchronized";
  case Modifier.STRICT:
   result = "strict";
  case Modifier.TRANSIENT:
   result = "transient";
  case Modifier.VOLATILE:
   result = "volatile";
  case Modifier.INTERFACE:
   result = "interface";
  }
  return result;
 }

 public static void printClassDefinition(Class clz) {

  String clzModifier = getModifier(clz.getModifiers());
  if (clzModifier != null && !clzModifier.equals("")) {
   clzModifier = clzModifier + " ";
  }
  String superClz = clz.getSuperclass().getName();
  if (superClz != null && !superClz.equals("")) {
   superClz = "extends " + superClz;
  }
  Class[] interfaces = clz.getInterfaces();
  String inters = "";
  for (int i = 0; i < interfaces.length; i++) {
   if (i == 0) {
    inters += "implements ";
   }
   inters += interfaces[i].getName();
  }
  System.out.println(clzModifier + clz.getName() + " " + superClz + " "
    + inters);
  System.out.println("{");
  Field[] fields = clz.getDeclaredFields();
  for (int i = 0; i < fields.length; i++) {
   String modifier = getModifier(fields[i].getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String fieldName = fields[i].getName();
   String fieldType = fields[i].getType().getName();
   System.out.println("    " + modifier + fieldType + " " + fieldName
     + ";");
  }

  System.out.println();

  Method[] methods = clz.getDeclaredMethods();
  for (int i = 0; i < methods.length; i++) {
   Method method = methods[i];

   String modifier = getModifier(method.getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String methodName = method.getName();
   Class returnClz = method.getReturnType();
   String retrunType = returnClz.getName();

   Class[] clzs = method.getParameterTypes();
   String paraList = "(";
   for (int j = 0; j < clzs.length; j++) {
    paraList += clzs[j].getName();
    if (j != clzs.length - 1) {
     paraList += ", ";
    }
   }
   paraList += ")";
   clzs = method.getExceptionTypes();
   String exceptions = "";
   for (int j = 0; j < clzs.length; j++) {
    if (j == 0) {
     exceptions += "throws ";
    }
    exceptions += clzs[j].getName();
    if (j != clzs.length - 1) {
     exceptions += ", ";
    }
   }
   exceptions += ";";
   String methodPrototype = modifier + retrunType + " " + methodName
     + paraList + exceptions;

   System.out.println("    " + methodPrototype);
  }
  System.out.println("}");
 }
}


运行结果:
代码如下:

You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.fans.common.proxy.BusinessProcessor
{
    java.lang.reflect.Method m1;
    java.lang.reflect.Method m3;
    java.lang.reflect.Method m0;
    java.lang.reflect.Method m2;

    boolean equals(java.lang.Object);
    java.lang.String toString();
    int hashCode();
    void processBusiness();
}


类BusinessProcessorHandler实现了InvocationHandler接口的invoke方法,这个类就是Proxy最终调用固定接口方法。

很明显,Proxy.newProxyInstance方法会做如下几件事:
    1,根据传入的第二个参数interfaces动态生成一个类,实现interfaces中的接口,该例中即BusinessProcessor接口的processBusiness方法。并且继承了Proxy类,重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了$Proxy0类
    2,通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load
    3,利用第三个参数,调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化对象的几个Method成员变量
    4,将$Proxy0的实例返回给客户端。
现在好了。我们再看客户端怎么调就清楚了。
    1,客户端拿到的是$Proxy0的实例对象,由于$Proxy0继承了BusinessProcessor,因此转化为BusinessProcessor没任何问题。
         BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
    2,bp.processBusiness();
         实际上调用的是$Proxy0.processBusiness();那么$Proxy0.processBusiness()的实现就是通过InvocationHandler去调用invoke方法啦!


    
 
 

您可能感兴趣的文章:

  • java map(HashMap TreeMap)用法:初始化,遍历和排序详解
  • 哪位java同门师兄有《java2编程详解》电子文档,注意不是影印版
  • 请问哪儿有java2编程详解的电子书下载??本人急需!!跟贴有分!!!
  • 谁有JAVA的类库详解或下载地址?
  • 请问那里有《JAVA2编程详解》可以下载?
  • 《Java 2 编程详解》程序清单14.12中的一个问题。
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • 我非常想知道JAVA跟C/C++对于硬件控制的能力孰强孰弱.(菜鸟问题,要详解,在线等待)
  • Java中的随机数详解
  • 深入分析Java内存区域的使用详解
  • Java加载JDBC驱动程序实例详解
  • Java代码重构的几种模式详解
  • JAVA中list,set,数组之间的转换详解
  • Java中关于int和Integer的区别详解
  • java equals函数用法详解
  • Java I/O技术之文件操作详解
  • java this super使用方法详解
  • java全角、半角字符的关系以及转换详解
  • 深入JAVA对象深度克隆的详解
  • 深入Java不可变类型的详解
  • 浅谈java中静态方法的重写问题详解
  • java代理 jdk动态代理应用案列
  • 移动开发 iis7站长之家
  • 请问各位高手,如何用JAVA编一个代理服务器。
  • 如何用Java做代理,在线等待!!
  • Java类动态代理框架 Smartproxy
  • Java 的 MQTT 代理 Moquette-mqtt
  • Java的HTTP代理服务器 Smart Cache
  • Java动态代理 CGLib
  • 如何代理SUN 的JAVA认证和考试,DJLIHAO@SINA.COM,请将相关协议发到此信箱。500分,在线等
  • 如何代理SUN 的JAVA认证和考试,DJLIHAO@SINA.COM,请将相关协议发到此信箱。500分,在线等
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • 不太明白,利用RMI实现JAVA分布式应用 和 EJB实现JAVA分布式应用有什么区别。
  • 如何设置java应用程序的风格,如java风格,和windows风格!
  • Java GUI应用程序开发框架 Axualize
  • Java应用服务器 Virgo
  • JAVA桌面应用服务器 JDAP
  • Java与桌面应用程序
  • Java应用漏洞检测工具 LAPSE+
  • Java 应用自动更新框架 Jupidator
  • 讨论:Java是否适合编写通常的应用程序?
  • 怎样让java应用程序独立运行?
  • 求教!!!VC应用调用Java模块可行吗?
  • Java 应用服务器 WildFly
  • Java企业应用开发框架 Portofino
  • Web应用框架 Pulse-java
  • 求JAVA的具体应用
  • Java模块化应用开发框架 JTheque
  • 请问如何通过telnet的方式启动服务器(solaris)上的用.sh角本方式启动java写的应用程序,在退出telnet时服务器上的应用程序不会退出?
  • Java 应用程序维护工具 MaintainJ
  • 只考虑WEB应用, JAVA适合吗? 除了IIS, 我还能让什么东西来支持我的ASP? JAVA有关的东东有没有好办法?
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 如何将java.util.Date转化为java.sql.Date?数据库中Date类型对应于java的哪个Date呢
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 我对JAVA一窍不通,可惜别人却给我一个Java的project,要我做一个安装程序,请问哪里有JAVA INSTALLER下载,而且我要不要安装java的sdk才能完成此项任务?
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 新年第一天,让我们讨论一下未来一年JAVA的发展趋势! 个人认为,JAVA将主要朝ERP和JAVA手机方面发展!
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: stringflavor定义及介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3