java中的动态代理_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java中的动态代理

java中的动态代理

 2012/4/27 13:48:17  还可以  程序员俱乐部  我要评论(0)
  • 摘要:首先明确代理模型中的两个实体:代理类和委托类(处理器)代理类:JVM中的代理类都是Proxy的子类,并且其字节码是由JVM动态产生的,代理类字节码字节数组是调用ProxyGenerator的generateProxyClass(Stringarg0,Class[]interfaces)方法生成的。代理类会将请求委派给委托类执行。委托类:也称作处理器,其会实现接口InvocationHandler,其接口中只有一个方法invoke,实际的处理逻辑都会放入其中
  • 标签:Java 代理

首先明确代理模型中的两个实体:代理类和委托类(处理器)

代理类:JVM中的代理类都是Proxy的子类,并且其字节码是由JVM动态产生的,代理类字节码字节数组是调用ProxyGeneratorgenerateProxyClass(String arg0, Class[] interfaces)方法生成的。代理类会将请求委派给委托类执行。

委托类:也称作处理器,其会实现接口InvocationHandler,其接口中只有一个方法invoke,实际的处理逻辑都会放入其中。

?

关于代理类的对象的产生

这是通过Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法进行产生的,解释一下其中的三个参数,loader为装载此代理类字节码的类装载器,interfaces会作为最终产生代理类字节码的材料来源之一(ProxyGenerator.generateProxyClass(String arg0, Class[] interfaces)),h为处理器.

?

关于JVM生成的代理类的类名

都为ProxyN,其中N为当前JVM实例中生成的代理类的个数,由一个静态整型变量记录,创造一个N值累加一下。每个代理类的class对象都会被缓存Proxy的一个map对象中,这样做的好处是当在同一个classloader中需要同一个代理类时,就不需要重复去创造已有的代理类了,直接从map中取用class对象即可。减少了字节码构建和装载时JVM的性能消耗。

?

使用代理类的好处

因为代理类是使用反射在JVM运行时动态产生的,所以其使用有很好的灵活性,可以在任何业务逻辑之前和之后加入自己想加入的代码,spring中的aop就使用了此项技术。

?

自己写了一个代理的demo

在这个demo中,想在Studentsay方法逻辑之前和之后加入其它代码,处理器为Teacher

接口People:

package com.proxy;

?

public interface People {

? public void say();

}

?

Student实体:

package com.proxy;

?

public class Student implements People {

?

???????? @Override

???????? public void say() {

???????????? System.out.println("Student say");

???????? }

?

}

?

Teacher实体:

package com.proxy;

?

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

?

public class Teacher implements InvocationHandler {

??? private People people;

???????? public Teacher(People people){

??? ???????? this.people = people;

??? }

???????? @Override

???????? public Object invoke(Object proxy, Method method, Object[] args)

??????????????????????????? throws Throwable {

?????????????????? System.out.println("before");

?????????????????? people.say();

?????????????????? System.out.println("teacher say");

??????? System.out.println("after");

?????????????????? return null;

???????? }

?

}

测试类ProxyTest

package com.proxy;

import java.lang.reflect.Proxy;

public class ProxyTest{

??? public static void main(String[] aa){

??? ???????? Student student = new Student();

??? ???????? Teacher teacher = new Teacher(student);

??? ???????? People people = (People)Proxy.newProxyInstance(student.getClass().getClassLoader(), student.getClass().getInterfaces(), teacher);

??? ???????? people.say();

??????? System.out.println(Proxy.isProxyClass(people.getClass()));

??????? System.out.println(people.getClass().getName());

??? }

?

}

?

输出结果为:

before

Student say

teacher say

after

true

$Proxy0

这里再附上一篇详细讲解java中动态代理的文章http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/

这里还有一篇动态代理和静态代理对比的文章http://blog.csdn.net/sunyujia/article/details/2500684

发表评论
用户名: 匿名