它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
代理可以分静态代理和动态代理
两个场景简单的说明下两者:
静态代理:
例:霖哥是老板,有签字,开会的功能,公务繁忙,所以找了个小蜜,有什么事先经过小蜜,通过小蜜之后再到霖哥那,但是具体做的事情(比如签字,开会)还是霖哥做,这个小蜜就相当于是代理.
动态代理:
例:比如霖哥,亚淞还有山山要学外语,于是找到了一个外语辅导班,但是霖哥要学的是日语,亚淞要学英语,山山要学法语于是辅导班就给霖哥安排了一个日语老师(美女哦),给亚淞安排了一个英语老师(非洲来的猛汉,哈哈)给山山安排了一个法语老师(法国小鲜肉,男的).这时这个外语辅导班就相当于动态代理.
代码:
静态代理:
interface Subject{
//定义抽象方法play()
public String play (String name, int age);
}
class RealSubject implements Subject {
public String play(String name, int age) {
return "姓名: " + name + ",年龄:" + age;
}
}
class ProxySubject implements Subject{
private Subject sub = null;
public ProxySubject(Subject sub){
this.sub = sub;
}
public String play(String name , int age){
return this.sub.play(name,age);
}
}
public class StaticProxyDemo {
public static void main(String args[]){
Subject sub = new ProxySubject(new RealSubject());
System.out.print(sub.play("汪庆邦",24));
}
}
动态代理:
在java中要想实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持
InvocationHandler接口的定义如下:
public interface InvocationHandler{
public Object invoke(Object proxy,Method method, Object[] args) throws Throwable
}
invoke()方法中的三个参数的意义依次是:被代理的对象、要调用的方法、方法调用时所需要饿参数。
Proxy 类是专门完成代理的操作类,可以通过此类为一个或者多个接口动态的生成实现类。Proxy提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader ,Class<?>[] interface, InvocationHandler h) throws IllegalArgumentException
通过newProxyInstance()方法可以动态的生成实现类。此方法中参数的意义依次为:
类加载器,得到全部的接口,得到InvocationHandler接口的子类实例。
先定义一个InvocationHandler接口的子类,以完成代理的具体操作。
public class MyInvocationHandler implements InvocationHandler
{
private Object obj;//真实的主题
public Object bind(Object obj){//绑定真实操作主题
this.obj = obj;
//取得代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
//动态调用方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object temp = method.invoke(this.obj,args);
return temp;
}
}
在类的bind() 方法中接受被代理对象的真实主题实现,之后覆写InvocationHandler接口中的invoke () 方法,完成具体的方法调用。
定义接口
interface Subject{
//定义抽象方法play()
public String play (String name, int age);
}
定义真实主题实现类
class RealSubject implements Subject {
public String play(String name, int age) {
return "姓名: " + name + ",年龄:" + age;
}
}
以上定义了接口及真实主题类,这样在操作时直接将真实主题类的对象传入到MyInvocationHandler类的bind() 方法中MyInvocationHandler类的bind() 方法中即可。
public class DynaProxyDemo {
public static void main(String args[]){
//实例化代理类操作
MyInvocationHandle handler = new MyInvocationHandle();
Subject sub = (Subject)handler.band(new RealSubject());// 绑定对象
System.out.println(sub.play("汪庆邦",24));
}
}