一、代理模式概念
-
定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在被代理的对象和目标对象之间起到中介的作用。*例如,你(真实角色)要打官司(抽象角色)告张三(真实角色)偷了你家的鸡蛋,你请了一个律师(代理角色),那这个律师就相当于你的代理对象,你这个被代理的对象就只需要坚定张三就是偷了你家鸡蛋的核心需求就行了,准备资料、向法官提交资料等琐碎的是你的代理对象律师会帮你搞定。
-
角色:
抽象角色: 包含真实角色需要实现的核心业务的接口或者类
真实角色: 实现抽象角色的类
代理角色: 代理真实角色的类,对真实角色进行业务扩展 -
优点:
(1)解耦合、高扩展性: 添加新的需求不需要修改原来的代码
(2) 职责清晰: 真实角色只需要实现自身的核心业务,而不需要考虑其他非自身职责的需求
静态代理是在编译前已经确定的代理关系,动态代理是通过反射在程序运行中 生成的代理关系。
二、代理模式分类
1、 静态代理
下面通过打官司的例子来实现静态代理模式:
抽象角色:打官司
真实角色:原告
代理角色:律师
(1)抽象角色:
/**
* @Author 吕小白
* @Interface Lawsuit
* @Description: 抽象角色:打官司
* @Date 2021/8/27 16:21
* @Version 1.0
**/
public interface Lawsuit {
// 打官司的诉求
public void appeal(String testimony);
}
(2)真实角色:
/**
* @Author 吕小白
* @ClassName Plaintiff
* @Description:真实角色:原告
* @Date 2021/8/27 16:25
* @Version 1.0
**/
public class Plaintiff implements Lawsuit{
// 实现抽象角色的业务,提出你的诉求
@Override
public void appeal(String testimony) {
System.out.println(testimony);
}
}
(3)代理角色
/**
* @Author 吕小白
* @ClassName Lawyer
* @Description:代理角色:律师
* @Date 2021/8/27 16:28
* @Version 1.0
**/
public class Lawyer implements Lawsuit{
// 被代理的对象
private Lawsuit target;
public Lawyer(Lawsuit target) {
this.target = target;
}
//实现抽象角色的业务
@Override
public void appeal(String testimony) {
// 实现真实角色需求前
before();
// 实现真实角色的需求
target.appeal(testimony);
// 实现真实角色需求后
after();
}
// 代理对象扩展的业务
public void before(){
System.out.println("打官司前准备资料");
}
public void after(){
System.out.println("打完官司收费");
}
}
(4)测试运行
public class MainTest {
public static void main(String[] args) {
// 创建真实对象:原告
Plaintiff plaintiff = new Plaintiff();
// 创建代理对象:律师
Lawyer lawyer = new Lawyer(plaintiff);
lawyer.appeal("状告张三偷了鸡蛋");
}
}
2、 动态代理
下面是提供接口基于JDK实现的动态代理两个关键类和接口:
(1)Proxy类:newProxyInstance(ClassLoader loader, Object<?>[] interfaces, InvocationHandler h)
- loader: 类加载器
- interfaces: 真实角色的接口数组
- h: InvocationHandler接口的实现类对象
(2)InvocationHandler接口:invoke(Object proxy, Methoh method, Object[] args)
代码实现: 下面继续引用上面的例子,抽象角色和真实角色保持不变
1、代理角色代码:
public class DynamicProxy implements InvocationHandler {
// 要被代理的真实对象
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
//获取代理对象
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 实现真实角色需求前
before();
// 调用方法
Object result = method.invoke(target, args);
// 实现真实角色需求后
after();
return result;
}
// 代理对象扩展的业务
public void before(){
System.out.println("打官司前准备资料");
}
public void after(){
System.out.println("打完官司收费");
}
}
2、测试代码:
public class MainTest {
public static void main(String[] args) {
// 创建真实对象:原告
Lawsuit plaintiff = new Plaintiff();
// 创建代理对象:律师
DynamicProxy dynamicProxy = new DynamicProxy(plaintiff);
Lawsuit proxy = (Lawsuit) dynamicProxy.getProxy();
proxy.appeal("张三偷了鸡蛋");
}
}