首先,代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。其组成包括三部分:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
三个角色的关系为:抽象类或接口提供抽象方法,具体类实现抽象方法,代理类通过代理具体类并实现相关方法使客户端在调用具体类方法时不用知道实现类的细节,即可以修改实现部分实现方法。以上关系可以通俗的通过明星的运作模式来举例:抽象角色(会演戏,唱歌的明星),真实角色(张学友),代理角色(张学友经纪人),当某个综艺节目需要张学友来唱歌时会通过联系经纪人来确定歌神本人有没有档期,而不是直接联系张学友。
举例:public interface Star {//接口
public void sing();
public void acting();
}
public class ZXY implements Star {//具体类
public void sing() {
System.out.println("歌神唱歌很贵");
}
public void acting() {
System.out.println("歌神拍电影很贵");
}
}
public class Agent implements Star {//代理类
private Star s;
public Agent(Star s ){
this.s=s;
}
public void sing() {
s.sing();
}
public void acting() {//经纪人拒绝歌神拍电影的通告
s.acting();
System.out.println("歌神不拍电影了");
}
}
public class TV {//客户端的调用
public static void main(String[] args) {
ZXY z=new ZXY();
Star s=new Agent(z);
s.acting();
s.sing();
}
}
运行结果:
以上为静态代理内容。
上述过程中,当综艺电视台需要请多个明星时就需要寻找到每一个Star的Agent类,如果我们能有一个平台帮我们省略掉找每一个Star的Agent的过程会不会更好呢,所以动态代理出现了
动态代理它可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在。动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。其中Java.lang.reflect.Proxy类可以直接生成一个代理对象
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TV {
public static void main(String[] args) {
/*ZXY z=new ZXY();
Star s=new Agent(z);
s.acting();
s.sing();*/
//Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
//ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。
//Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。
//InvocationHandler:策略(方案)设计模式的应用。如何代理?
final Star s=new ZXY();
Star proxy=(Star) Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o=method.invoke(s, null);
return o;
}
});
proxy.sing();
proxy.acting();
System.out.println("歌神不拍电影了");
}
}