一.定义
为其他对象提供一种代理以控制对这个对象的访问。
二.类图
2.1 通用类图
- Subject抽象主题角色。可以是抽象类也可以是接口,是一个普通的业务类型定义,无特殊要求。
- RealSubject具体主题角色。业务逻辑的具体执行者。
- Proxy代理主题角色。负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
三.优点
- 职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务。
- 高扩展性。具体主题角色是随时都会发生变化的,只要它实现了接口,不管如何变化,代理类完全可以在不做任何修改的情况下使用。
四.扩展
- 普通代理。它的要求就是客户端只能访问代理角色,而不能访问你真实角色。真实主要通过构造函数限制谁能创建对象。在该模式下,调用者只知道代理而不用知道真实角色是谁,屏蔽了真实角色的变更对高层模块的影响,该模式非常适合对扩展性要求比较高的场合。在实际项目中,一般都是通过约定来禁止new一个真实的角色。
- 强制代理。要从真实角色查找到代理角色,不允许直接访问真实角色。
- 多角色代理。一个类可以实现多个接口,完成不同任务的整合。也就是说代理类不仅仅可以实现主题接口,也可以实现其他接口完成不同的任务,而且代理的目的是在目标对象方法的基础上做增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。代理类可以为真实角色预处理信息、过滤消息、消息转发等。一个代理类,可以代理多个真实角色,并且真实角色之间可以有耦合关系。
- 虚拟代理。在需要的时候才初始化主题对象,可以避免被代理对象较多时而引起的初始化缓慢的问题。其缺点是需要在每个方法中判断主题对象是否被创建,这就是虚拟代理。
- 动态代理。动态代理是在实现阶段不用关心代理谁,而是在运行阶段才指定代理哪一个对象。相对来说自己写代理类的方式,就是静态代理。Spring中AOP的核心是动态代理。动态代理是根据被代理的接口生成所有方法,也就是说给定一个接口,动态代理会宣称“我已经实现该接口下的所有方法了”。动态代理怎么才能实现被代理接口中的方法呢?默认情况下所有的方法返回值都是空的,是的,代理已经实现它了,但是没有任何的逻辑含义,那怎么办?通过InvocationHandler接口,所有方法都由该Handler来进行处理,即所有被代理的方法都由InvocationHandler接管实际的处理任务。要实现动态代理的首要条件是:被代理类必须实现一个接口。当然了也有很多技术如CGLIB可以实现不需要接口也可以实现动态代理的方式