代理模式
代理模式是设计模式之一,代理类和委托类有相同的接口,代理类主要负责为委托类预处理信息,过滤信息,把消息转发给委托类。
- 委托类(RealSubject):实现类接口所给定的具体的方法实现
- 代理类(Proxy):提供代理功能,对外提供服务(客户端Client访问代理类),代理类对象本身并不真正提供服务,而是由委托类提供服务
- 接口(Subject):委托类和代理类是该接口的实现类
- 客户端(Client):进行调用服务(与代理类打交道)
以房地产开发为例:
- 房地产公司即是接口类,负责设计房地产;
- 购房者:买房(客户端);
- 销售:与购房者进行沟通,在销售进行购买服务(代理类);
- 农民工:进行建房(委托类,真正实现功能);
静态代理在编译阶段就能确定代理类,动态代理在运行阶段确定代理类;动态代理在运行时根据java带的“指示”动态生成,相比较静态代理,动态代理的优势是方便对代理类的函数进行统一管理,而不用修改每个代理中的方法。
Java中动态代理的实现方式:JDK自带的动态代理和CGLib实现的代理
JDK自带的代理方式
该实现方式必须有一个接口,还需要一个委托类来做接口的真正实现。
接口:
/**
* 接口:代理类和委托类共享接口
*/
public interface IUser {
void talk();
}
委托类:
/**
* 委托类:是接口的真正实现类
*/
public class RealUser implements IUser{
@Override
public void talk() {
System.out.println("RealUser is talking");
}
}
实现动态代理,需要辅助类来实现InvocationHandler
/**
* 动态代理辅助类:实现一个InvocationHandler接口
*/
public class UserProxy implements InvocationHandler {
//在辅助类中保存委托类的引用
private IUser user;
public UserProxy(IUser user) {
super();
this.user = user;
}
/**
* 实现InvocationHandler接口的类,需要实现invoke方法,方法三个参数是:
*
* @param proxy :动态代理生成的代理类对象
* @param method:就是调用的方法
* @param args :方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理类可以实现特有的功能
System.out.println("Proxy start...");
//通过method的invoke方法来讲委托类指定,以及该方法的参数传递
method.invoke(user,args);
//代理类可以实现特有的功能
System.out.println("Proxy end...");
return null;
}
}
产生代理类,需要使用Proxy类
//动态代理的使用
/**
* 动态代理产生使用Proxy.newProxyInstance方法生成,有三个要素
* ClassLoader loader:指定当前的加载器即可
* Class<?>[] interfaces:被代理的接口
* InvocationHandler h :代理辅