1. 首页
  2. >
  3. 编程技术
  4. >
  5. Java

聊聊实现AOP框架的代理模式

AOP(面向切面编程) 要达到的效果就是:在开发者不修改业务组件源代码的前提下,为这个业务组件添加某种通用功能。

AOP的实现方式

如果不在开发阶段去修改业务组件源代码,那么我们要在什么时候添加通用功能的代码呢?那就只能是在开发阶段之后,由AOP框架自动修改了源代码。

按照 AOP 框架修改源代码的时机,大致可以分为两类实现方式:

  • 静态 AOP 实现:AOP 框架在编译阶段对程序代码进行修改,生成了静态的 AOP 代理类。原来业务组件源代码生成的 *.class 文件已经被改掉了,这种实现方式需要使用特定的编译器,比如 AspectJ。
  • 动态 AOP 实现:AOP 框架在运行阶段动态生成代理对象,程序要通过代理对象来访问业务组件的方法,在代理对象中添加通用功能的代码,如 Spring AOP。

本文重点介绍Spring AOP 的动态代理机制,在介绍动态代理之前,我们先从代理模式说起。

代理模式

代理模式是GoF的23种经典设计模式(Design Pattern)之一,属于结构型设计模式。简单说就是:给某一个对象提供一个代理,由代理对象来控制对真实对象的访问。

这就好比单位领导有一位秘书,下属要找领导审批文件都要通过他的秘书,而领导也都通过秘书来传达他的指令,平时大家只和这个秘书打交道,秘书就相当于这位领导的代理。

聊聊实现AOP框架的代理模式

代理模式:老板与下属的所有交互都由秘书代为完成,秘书就是老板的代理

代理模式角色分为 3 种:

Subject(抽象主题角色):定义代理类和真实主题的公共对外方法;

RealSubject(真实主题角色):真正实现业务逻辑的类;

Proxy(代理主题角色):用来代理和封装真实主题的类;

聊聊实现AOP框架的代理模式

代理模式

代理模式的结构比较简单,核心是代理类。Client通过代理类来访问真实业务组件。我们先通过静态代理来说明代理模式如何实现业务组件的功能增强。

聊聊实现AOP框架的代理模式

静态代理实现增强代码(advice)的引入

如上图,代理类 ServiceProxy 和业务类 Service 继承自同样的接口。代理类 ServiceProxy 中包含了一个业务类的目标对象 target,创建代理类对象的时候要完成目标对象的注入。

客户类 Test 调用代理类 ServiceProxy 对象的方法 method(),在代理类中重写了method()方法,在原业务类 Service 的方法method()基础上增加了增强代码 before()after()。这样就实现了在不侵入业务组件代码的前提下,完成了业务组件的功能增强。

动态代理更胜于静态

静态代理虽然实现简单,但是当场景稍微复杂一些的时候,静态代理的缺点也会暴露出来。

1、 当需要代理多个类的时候,要么是一个代理类实现多个类的接口,这样会导致代理类过于庞大;要么是为每个目标类都开发一个代理类,这样又会产生过多的代理类。

2、 当接口需要增加、删除、修改方法的时候,业务类与代理类都要同时修改,不易维护

更好的办法是为每个目标类动态生成代理对象,不需要为每个目标类维护一套代理类的代码。动态代理的意思就是根据接口或目标对象,计算出代理对象的字节码,然后再加载到JVM中使用。

Spring AOP有两种动态代理的方式:

  1. 实现接口的方式:如果目标类继承自接口,那么可以通过实现接口的方式,类似静态代理,通过接口来生成对应的代理类;
  2. 继承目标类的方式:如果目标类没有接口,那么可以通过生成目标类的子类来做代理类。

对于Spring AOP动态代理的具体实现方式,我们在后续文章中再做介绍。

前端:ElementUI+VUE 日期控件禁用用法
« 上一篇 2021年02月04日 pm22:51
新专利显示未来Apple Watch显示屏和机壳可能会提升无线接收能力
下一篇 » 2021年02月05日 am00:03

相关推荐