Android_Banner.jpg
定义
- 代理模式也被称为委托模式,它是结构型设计模式的一种。
- 定义:为其他对象提供一种代理以控制这个对象的访问。
- Proxy(代理)
- 从代理角度来说,代理模式分为静态代理和动态代理
代理模式的UML图
代理模式UML图.png
角色解释
- Subject:抽象的主题类,声明了真实主题类和代理类共同要实现的方法
- RealSubject:真实主题类(被代理类),代理类所代表的真实主题。客户端通过代理类间接调用真实主题类中的方法。
- Proxy:代理类,持有了真实主题的对象,在其实现的方法中调用了真实主题类中相应的接口方法。
- Client:客户端,调用者。
场景设定以及实现
我好久没回大连了,但是想吃吃大连的海鲜。但是由于距离遥远、工作繁忙不能回大连吃一顿,我就委托了我的好朋友李麒帮我买了一箱海鲜。
- 相面根据静态代理和动态分别作出不同的实现
静态代理
抽象主题类
public interface ISeaFoodSubject {
void buy();
}
定义真实的主题类
public class SeaFoodRealSubject implements ISeaFoodSubject{
@Override
public void buy() {
System.out.println("买了一箱海鲜,🦪、🦐、🦀️、海胆、");
}
}
定义代理类
public class LQProxy implements ISeaFoodSubject {
private ISeaFoodSubject mISeaFoodSubject;
public LQProxy(ISeaFoodSubject iSeaFoodSubject) {
mISeaFoodSubject = iSeaFoodSubject;
}
@Override
public void buy() {
mISeaFoodSubject.buy();
}
}
客户端调用
public class SeaFoodClient {
public static void main(String[] args) {
ISeaFoodSubject seaFoodRealSubject = new SeaFoodRealSubject();
ISeaFoodSubject proxy = new LQProxy(seaFoodRealSubject);
proxy.buy();
}
}
代理模式可以在不修改被代理类对象的基础上,通过扩展代理类,进行一些功能的附加与增强。
为什么叫静态?因为它的类型是事先预定好的,比如上面的LQProxy类
动态代理
在静态代理中,在代码运行前就已经存在了代理类的class编译文件;而动态代理则是在代码运行时通过反射来动态的生成代理类得对象,并确定到底来代理谁。
- Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法。
场景设定和实现
假设有一个很大的海鲜商场,有很多专门卖海鲜的摊位,有一个摊位专门卖🦪。
-
创建抽象主题类,海鲜商场中的摊位(作用是卖🦪)
public interface ISeaFoodTall { void sellSeaFood(); }
-
创建真正的主题类,海鲜🦪
public class ShengHao implements ISeaFoodTall { @Override public void sellSeaFood() { System.out.println("我卖的是生蚝"); } }
-
创建动态代理类,也就是卖海鲜的摊位
public class TanWeiA implements InvocationHandler { private Object mObject; public TanWeiA(Object object) { mObject = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if (name.equals("sellSeaFood")) { method.invoke(mObject, args); } return null; } }
-
创建客户端类,调用卖海鲜的过程
public class TestClient { public static void main(String[] args) { ShengHao shengHao = new ShengHao(); TanWeiA tanWeiA = new TanWeiA(shengHao); ISeaFoodTall iSeaFoodTall = (ISeaFoodTall) Proxy.newProxyInstance(ShengHao.class.getClassLoader(), ShengHao.class.getInterfaces(), tanWeiA); iSeaFoodTall.sellSeaFood(); } } -
运行结果
// 我卖的是生蚝
动态代理的语法
在上文中我们正是通过Proxy的静态方法newProxyInstance()才会创建的动态代理
Prxoy
-
newProxyInstance()
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) { }- loader:是类的加载器
- interfaces 要用来代理的接口
- h 一个InvocationHandler的对象
-
InvocationHandler
每一个代理实例都有一个与之关联的InvovationHandler实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的InvocationHandler实现类,由它决定。
-
InvocationHandler 是一个接口
-
内部只有一个invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;- proxy 代理对象
- method 代理对象调用的方法
- args 调用的方法中的参数
-
代理的作用
- 面向切面编程(AOP)
总结
- 代理分为静态代理和动态代理
- 静态代理,需要自己实现代理类
- 动态代理,代理类通过Proxy.newProxyInstance()来生成
- 动态代理通过Proxy动态生成proxy class,但是它也指定了一个InvovationHandler的实现类。
- 代理模式在本质的目的是为了增强现有代码的功能。









网友评论