首先了解一下代理作用:
代理解藕,是的接口实现类与业务代码解藕,无需通过调用接口实现类却不仅仅实现了接口的方法而且对该方法增加,同时也使得代码的逻辑层次清晰。
首先我们看看静态代理:
/**
* 接口
* Created by ykanghe on 12/28/16.
*/
public interface SimpleInterface {
public void sayHello(String str);
}
/**
* 实力类
* Created by ykanghe on 12/28/16.
*/
public class SimpleRealInstance implements SimpleInterface {
@Override
public void sayHello(String str) {
System.out.print(str);
}
}
/**
* 代理类
* Created by ykanghe on 12/28/16.
*/
public class StaticProxy implements SimpleInterface {
private SimpleRealInstance instance;
public StaticProxy(SimpleRealInstance instance) {
this.instance = instance;
}
@Override
public void sayHello(String str) {
System.out.print("Tom:");
this.instance.sayHello(str);
}
}
/**
* 客户端
* Created by ykanghe on 12/28/16.
*/
public class Client {
public static void main(String[] arg) {
SimpleInterface proxy = new StaticProxy(new SimpleRealInstance());
//入参是 say hello to u 但是好像少了人称,这个时候需要加人称,这个通过代理类完成了咯。
proxy.sayHello("say hello to u ");
//实际输出结果:Tom say hello to u;
}
}
结果:
从上述看我们可以看到代理对方法的加强,以及在不改动代码的基础上对实现了我们需要的方法,但是我们发现如果业务频繁的更改,或者需要不断的需改方法时候,我们需要大量重复的去写重复代码;
于是我们想到了反射,通过用反射实现动态代理,这样可以代理各种不同的对象,例子一样通过代理来实现主人称说话;
/**
* Created by ykanghe on 12/28/16.
*/
public interface DynamicInterface {
public void sayHello();
}
/**
* Created by ykanghe on 12/28/16.
*/
public class DynameicRealInstance implements DynamicInterface {
@Override
public void sayHello() {
System.out.print("i am a DynamicProxy");
}
}
/**
* 动态代理
* Created by ykanghe on 12/28/16.
*/
public class DynamicProxy implements InvocationHandler {
private Object tarObj;//被代理对象
public Object getTarObjDynamicProxy(Object tarObj) {
this.tarObj = tarObj;
//调用Proxy的静态方法newProxyInstance获得一个代理,入参分别是:代理类的加载器classloader,代理类的接口interface,需要实现代理的具体类invocationHandler
return Proxy.newProxyInstance(tarObj.getClass().getClassLoader(), tarObj.getClass().getInterfaces(), this);
}
//动态代理类只能代理接口(不支持抽象类),代理类都需要实现InvocationHandler类,实现invoke方法,在invoke中需要调用method.invoke
// 实力类的方法实现
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = null;
System.out.print("Tom:");
ret = method.invoke(tarObj, args);
return ret;
}
}
package Proxy.DynamicProxy;
/**
* Created by ykanghe on 12/28/16.
*/
public class DynameClient {
public static void main(String[] args) {
DynamicProxy proxy = new DynamicProxy();
DynamicInterface tarObjDynamicProxy = (DynamicInterface) proxy.getTarObjDynamicProxy(new DynameicRealInstance());
tarObjDynamicProxy.sayHello();
}
}