您的位置:首页 > 编程语言 > Java开发

JAVA AOP编程之动态代理技术

2012-03-15 23:15 405 查看
java中的代理是什么呢?

比如说我们用到一个类A ,我们往常的方法就是直接使用这个类A ,这样在大型的软件开发中有很大的局限性、 。 我们对于使用的类A的修改只能通过对源文件硬编码的修改,

代理就很好的突破了这个瓶颈。

在代理中我们可以定义一个类B,这个类B有个特点 就是和类A有着实现同样的接口 ,我们在类B中间接的调用了 类A, 我们也可以向这个代理的类插入一些通告消息类 。

着在开发框架中经常用到 。

在JAVA中用于动态生成代理类的类 就是 java.lang.reflect.Proxy 这个类 具体的使用 可以去 看看有关于JDK的文档 。

在AOP的程序设计中,InvocationHandler 这个类是作为代理类对于target类的间接调用者 ,所有的被代理类都是通过 这个InvocationHandler这个类来进行调用的 。

我们在对这些步骤进行操作的时候 只需要把实现过程封装起来 把 需要代理的类 作为Object传递进去 那么就可以实现 代理的通用化 ,于是一个小java框架就产生了 。

在使用的过程用 涉及到匿名内部类 ,这里提到 在匿名内部类中调用外部的对象 需要 吧外面的对象 声明为 final 。。。。 这是java的语法 为了是保证数据的安全性。。

StirngBuffer是一个线程安全的类,继承了String在多线程中用到 。

如果只涉及到 单线程那么 就用 StringBuilder这个类 效率会提高很多。。

关于代理的结构图如下:



下面我写一个例子来实现动态代理 :

package me.test;

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

import java.lang.reflect.TypeVariable;

public class MyProxy

{

public static void main(String []args) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException

{

Class clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class) ; //利用Proxy类产生一份代理类的字节码

//Create a Dynamic Class by using Proxy

Constructor constructors[]=clazzProxy.getConstructors() ; //获得代理类的构造方法数组 反射原理

Method []methods=clazzProxy.getMethods() ; //获得代理类的方法

System.out.println("Constructor List:");

for(Constructor con:constructors)

{

String cons=con.getName() ;

StringBuilder conBuilder=new StringBuilder(cons) ;

Class []types = con.getParameterTypes() ;

conBuilder.append('(') ;

if(types.length!=0&&types!=null)

{

for(Class type:types)

{

conBuilder.append(type.getName()) ;

conBuilder.append(',') ;

}

conBuilder.deleteCharAt(conBuilder.lastIndexOf(",")) ;

}

conBuilder.append(')') ;

System.out.println(conBuilder);

}

System.out.println("Methoid list:");

for(Method med:methods)

{

String cons=med.getName() ;

StringBuilder conBuilder=new StringBuilder(cons) ;

Class []types = med.getParameterTypes() ;

conBuilder.append('(') ;

if(types.length!=0&&types!=null)

{

for(Class type:types)

{

conBuilder.append(type.getName()) ;

conBuilder.append(',') ;

}

conBuilder.deleteCharAt(conBuilder.lastIndexOf(",")) ;

}

conBuilder.append(')') ;

System.out.println(conBuilder);

}

/////////////////////////////////////////////////////////////这里是代理类的实现部分

class MyInvocationHandler implements InvocationHandler

{

@Override

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

throws Throwable {

// TODO Auto-generated method stub

return null;

}

}

Collection cn1=(Collection)constructors[0].newInstance((new MyInvocationHandler())) ; //生成一个代理类的对象 这个对象实现了 Collection接口

System.out.println(cn1.toString());

/*************************************************************************************/

Collection cn2=(Collection)constructors[0].newInstance(new InvocationHandler(){

@Override

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

throws Throwable {

// TODO Auto-generated method stub

return null;

}

}) ;

/***************************************************************************************/

final ArrayList list=new ArrayList() ;

Advice adv=new MyAdvice() ; //通告类 对象

Collection cn3 = getProxy(list, adv);

cn3.add("xiaowei") ; //会调用 对于代理类的操作会调用InvocationHandler的invoke方法 进行调用目标类 ,调用方法如同反射 机制

cn3.add("man") ;

cn3.add("软件技术") ;

System.out.println("包含"+cn3.size()+"个元素!") ;

for(Object obj:cn3)

{

System.out.println(obj.toString());

}

}

private static Collection getProxy(final Object list ,final Advice advice) {

Collection cn3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),

new Class[]{Collection.class},

new InvocationHandler()

/* @Override

public Object invoke(Object proxy, Method method, Object[] args) //代理类在执行每一个被代理类的方法的时候 就会调用这个invoke方法 并且传递Method对象 我们就可以动态的调用目的类的方法

throws Throwable {

// ArrayList list=new ArrayList() ; //必须作为一个成员来实现 否则 每次进行插入操纵那么调用的都是一个新的对象

Long beginTime=System.currentTimeMillis() ;

Object returnVal= method.invoke(list, args); //Invoke the Method

Long endTime=System.currentTimeMillis() ;

System.out.println("Runtime="+(endTime-beginTime));

return returnVal;

}*/

@Override

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

throws Throwable {

// ArrayList list=new ArrayList() ; //必须作为一个成员来实现 否则 每次进行插入操纵那么调用的都是一个新的对象

advice.beginRun(method) ; //内部类调用外部的对象的时候 需要使用 final声明

Object returnVal= method.invoke(list, args); //Invoke the Method 执行代理传递过来的执行方法

advice.afterRun(method) ;

return returnVal;

}

}

);

return cn3;

}

}

//////////////////////////////////////////////////////////////////////////通告接口 和实现类

package me.test;

import java.lang.reflect.Method;

public interface Advice

{

public void beginRun(Method method) ;

public void afterRun(Method method) ;

}

package me.test;

import java.lang.reflect.Method;

public class MyAdvice implements Advice{

long beginTime ;

@Override

public void beginRun(Method method ) {

beginTime=System.currentTimeMillis() ;

}

@Override

public void afterRun(Method method) {

long endTime=System.currentTimeMillis() ;

System.out.println(method.getName()+"运行了"+(endTime-beginTime)+"ms!");

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: