java代理技术一(jdk默认实现)

        很多框架和工具都是利用代理技术实现的。典型的如spring 的AOP、easymock、单元覆盖率检测工具等。静态代理比较好理解,就是自己写代理类来完成附加的功能,设计模式中专门有个代理模式讲这个。动态代理是指代理实现对象并不是在编译期间生成好的,而是在运行过程中产生的。这样的好处是当被代理的接口方法(注:jdk动态代理只能对接口进行代理)发生变化时,不需要改动代理实现类的代码。以下为示例代码:

假设有个接口:

public interface IDoSomething {
	public void doA();
	//public void doB();
}

一个常规的实现类:

public class DoSomethingImpl implements IDoSomething{

	@Override
	public void doA() {
		System.out.println("I'm working...");
	}
}

如果是静态代理,大概就写成这个样子:(静态代理通常实现和被代理类相同的接口)

public class StaticProxyDoSomething implements IDoSomething{
	private IDoSomething target;
	
	public StaticProxyDoSomething(IDoSomething target){
		this.target=target;
	}
	
	public void doA(){
		System.out.println("代理准备");
		target.doA();
		System.out.println("代理完成");
	}
	
//	public void doB(){
//		
//	}
}
可以看出,当接口方法发生变化,代理类里的方法也要跟着修改

动态代理类写成这样就可以了:

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

public class ProxyDoSomething implements InvocationHandler{
	private Object target;
	
	public ProxyDoSomething(Object target){
		this.target=target;
	}
	
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		Object result;
		System.out.println("准备工作...");
		result=method.invoke(target,args);
		System.out.println("代理完成...");
		return result;
	}	
}

        动态代理类需要实现InvocationHandler接口,覆写invoke方法。注意invoke方法中的第一个参数“proxy”容易引起混淆,它是一个隐含实现,对编码来说并没有用到。而执行method.invoke时需要给的是被代理对象。可以看出动态代理类就这么一些内容。未来不论接口再增加、修改了什么,代理类都不需要改写了。而且是执行被代理对象的每种接口方法都会调用这里的invoke,这就为我们提供一个方便的途径来进行“全局控制”,比如记录日志、权限检查什么的。

最后是一个简单的测试类:

import java.lang.reflect.Proxy;

public class TestProxy {
	public static void main(String[] args){
		DoSomethingImpl dsi=new DoSomethingImpl();
		
		IDoSomething proxy=(IDoSomething)Proxy.newProxyInstance(dsi.getClass().getClassLoader(), 
				dsi.getClass().getInterfaces(),new ProxyDoSomething(dsi));
		
		proxy.doA();
	}
}



你可能感兴趣的:(java,代理)