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

Java反射那点事(二)动态代理

2013-11-16 21:31 447 查看
代理四要素:

1.被代理对象实现的接口

2.代理逻辑类,须实现InvocationHandler接口,在invoke方法中实现代理的逻辑

3.产生代理对象:Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class[] { MyInterface.class }, handler);

4.调用代理对象的方法
代理机制及特点

1.通过实现 InvocationHandler 接口创建自己的调用处理器;

2.通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

3.通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

4.通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
应用场合

1.数据库连接和事务管理

2.Unit测试

3.Spring中的AOP
举例:

我临时想到的一个小例子,也不知道是否合适。比如歌手(Singer)是被代理对象,它实现了唱歌(Sing)接口

现在由歌手的经纪人(SingerBrokerHandler)做歌手的代理。在歌手唱歌之前,汇报一下,然后通知歌手要唱什么歌

等歌手唱完了,再汇报一下。在歌手休息前,汇报一下,之后再汇报一下。其中:代理人的汇报,就相当于我们添加的代理逻辑。在Handler的invoke方法中可以根据不同的方法添加不同的代理对象。

1.Sing接口

/*
* $filename: Sing.java,v $
* $Date: 2013-11-16 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2013-11-16 Nanjing,njupt,China
*/
public interface Sing {
public void say(String content);//唱歌
public void rest();//休息
}


2.Singer类
/*
* $filename: Singer.java,v $
* $Date: 2013-11-16 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2013-11-16 Nanjing,njupt,China
*/
public class Singer implements Sing{

@Override
public void say(String content) {
// TODO Auto-generated method stub
System.out.println("I am a singer, I want to sing a song ."+content);
}

@Override
public void rest() {
// TODO Auto-generated method stub
System.out.println("I want to hava a rest...");
}

}


3.代理逻辑SingerBrokerHandler
/*
* $filename: SingerBrokerHandler.java,v $
* $Date: 2013-11-16 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;

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

/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2013-11-16 Nanjing,njupt,China
*/
public class SingerBrokerHandler implements InvocationHandler {
Object target;
public SingerBrokerHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
// TODO Auto-generated method stub
if(method.getName().equals("say")){
System.out.println("代理人:歌手开始唱歌了...");
method.invoke(target,"代理人:歌曲的名字是:风吹麦浪...");//调用被代理对象的方法
System.out.println("代理人:歌手唱歌结束了,大家散伙吧...");
}else if(method.getName().equals("rest")){
System.out.println("代理人:歌手需要休息了...");
method.invoke(target);//调用被代理对象的方法
System.out.println("代理人:歌手休息好了...");
}
return null;
}

}


4.测试
/*
* $filename: TestProxy.java,v $
* $Date: 2013-11-16 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;

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

/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com
*2013-11-16 Nanjing,njupt,China
*/
public class TestProxy {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Singer singer = new Singer();
InvocationHandler invocationHandler = new SingerBrokerHandler(singer);
Sing singProxy = (Sing)Proxy.newProxyInstance(Sing.class.getClassLoader(),
new Class[] { Sing.class },
invocationHandler);
singProxy.say("我说了也没用...代理人让我唱啥我唱啥!");
singProxy.rest();
}

}


5.运行结果
代理人:歌手开始唱歌了...
I am a singer, I want to sing a song .代理人:歌曲的名字是:风吹麦浪...
代理人:歌手唱歌结束了,大家散伙吧...
代理人:歌手需要休息了...
I want to hava a rest...
代理人:歌手休息好了...

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