Java SE之旅_09_代理Proxy

在Java中,如何在不修改一个类的情况下对该类特定的方法执行特殊的任务呢?

Java提供了代理类Proxy来解决这种问题. 前提条件是被代理对象必须至少实现一个接口.


Proxy提供了静态方法newProxyInstance以创建代理对象,具体方法如下:

java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

其中,第一个参数loader指定运行类的类加载器,第二个参数指定被代理的对象实现的所有接口,第三个是InvocationHandler 接口,必须实现invoke方法以对被代理对象的方法进行拦截.


下面是个使用代理的小例子.

1. 定义一个接口MyInterface, 该接口有两个未实现的方法:

public interface MyInterface {
	void sayHi(String name);
	boolean close(); 
}

2. 定义接口 MyInterface的实现类MyInterfaceImpl:

public class MyInterfaceImpl implements MyInterface {

	@Override
	public void sayHi(String name) {
		System.out.println("hi! your name is: " + name);
		System.out.println();
	}

	@Override
	public boolean close() {
		System.out.println("the method close() is running...");
		return true;
	}

}

3. 定义测试类,使用Proxy对被代理对象obj进行代理,拦截在obj上执行的所有方法:

public class ProxyDemo {

	public static void main(String[] args) {
		//创建被代理对象obj
		final Object obj = new MyInterfaceImpl();
		
		//创建代理者,代理obj
		Object proxy = Proxy.newProxyInstance(
				ProxyDemo.class.getClassLoader(), // 指定该测试类的类加载器
				// 被代理的对象实现的所有接口,此处只有MyInterface这个接口
				new Class[]{MyInterface.class}, 
				new InvocationHandler(){//执行方法的句柄,是一个接口,只有一个方法invoke
					
					//invoke方法拦截所有在被代理对象obj上执行的方法,包括参数
					public Object invoke(Object proxy,Method method, Object[] args)
							throws Throwable {
						System.out.println("method's name = "+method.getName());
						
						//拦截参数
						if(null != args){
							System.out.println("args[0] is : " + args[0].toString());
						}else{
							System.out.println("no args... ");
						}
						
						//拦截方法
						if("close".equals(method.getName())){
							System.out.println("********** 拦截到close方法,测试一下不执行该方法**********");
							return false;
						}else{
							//把参数args传给obj,通过反射调用obj的method方法
							return method.invoke(obj, args);
						}
						
					} 
		}); 
		
		//将代理者强转成MyInterface,调用MyInterface定义的方法进行测试
		MyInterface impl = (MyInterface)proxy;
		impl.sayHi("小明");
		impl.close();
	}

}


运行结果:



在测试中,当执行句柄InvocationHandler的invoke方法拦截到impl的close方法时, 不执行close方法, 做到了在不修改原类MyInterfaceImpl的情况下对MyInterfaceImpl的close方法进行特殊处理, 这就是传说中的动态代理~~

当然,你也可以重新写个类继承MyInterfaceImpl,重写close方法,但是这样做会产生不少"没多大用途"的类,它们的职责只是为了修改一个方法... 而是用代理就比较灵活,体现了Java语言的动态代理机制.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值