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

代理四要素:
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...
代理人:歌手休息好了...

未经允许不得用于商业目的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值