今天我要介绍的设计模式叫做代理模式。对于这个设计模式相信大家应该是比较熟系的,spring中的AOP使用的就是动态代理模式。代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问(摘自百度百科)。通俗一点讲:代理模式就是在客户端调用和目标接口中间添加一个代理角色就好比中介。代理模式,装饰器模式和适配器模式都属于结构型设计模式,个人认为它们三个的实现思路都是一样的只是侧重点不同。适配器的特点在于兼容目标接口,装饰器的特点在于增强原有类的功能而代理模式的特点在于隔离调用类和被调用类。
代理模式分为静态代理模式和动态代理模式。所谓静态代理就是代理对象在程序运行前已经创建好了而动态代理则是在程序运行中动态的创建代理对象。
静态代理:1.首先创建一个公共的目标接口或抽象类。
public abstract class BaseController { public abstract void operationRequest(); }
2.定义一个调用类来实现目标接口或继承抽象类:
public class UserController extends BaseController{ @Override public void operationRequest() { System.out.println("接受用户请求"); } }
3.定义一个代理类:
public class UserControllerProxy extends BaseController{ private UserController userController = new UserController(); public void preOperationRequest(){ System.out.println("运行前置用户请求"); } @Override public void operationRequest() { preOperationRequest(); this.userController.operationRequest(); afterOperationRequest(); } public void afterOperationRequest(){ System.out.println("运行后置用户请求"); } }
4.客户端代码调用:
public static void main(String[] args) { BaseController proy = new UserControllerProxy(); proy.operationRequest(); } 运行结果: 运行前置用户请求 接受用户请求 运行后置用户请求
动态代理:在动态代理中我们不需要手动创建代理类而是通过反射创建代理类。我们使用的jdk自带的动态代理的实现。1.编写一个动态的处理器:
public class UserControllerHandler implements InvocationHandler { private Object object; public UserControllerHandler(final Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("运行前置用户请求"); Object result = method.invoke(object, args); System.out.println("运行后置用户请求"); return result; } }
2.客户端调用:
public static void main(String[] args) { BaseController baseController = new UserController(); BaseController proxy = (BaseController)Proxy.newProxyInstance(BaseController.class.getClassLoader(), new Class[]{BaseController.class},new UserControllerHandler(baseController)); proxy.operationRequest(); }
注意:jdk提供的动态代理仅支持接口,在这里我已经把BaseController由抽象类改成了接口。