千家信息网

如何进行Spring AOP框架实现的结构分析

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,如何进行Spring AOP框架实现的结构分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。从实现的角度来认识SpringAOP框架。观
千家信息网最后更新 2026年11月02日如何进行Spring AOP框架实现的结构分析

如何进行Spring AOP框架实现的结构分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

从实现的角度来认识SpringAOP框架。

观察的角度:

从外部接口,内部实现,组成部分,执行过程四个方面来认识SpringAOP框架。

本文的风格:

首先列出AOP的基本概念;

其次介绍框架所涉及到的核心组件列表,组件之间的结构关系图;

然后细化结构图中的部分;

接下来是一个简单的sample;

***是后记部分。

注:

1.本文的源代码基于Spring2.x。Spring的源代码也处于演变中,但对基础代码的影响并不大。

2.本文是对Spring IoC容器实现的结构分析的姊妹帖。

正文:

Spring AOP框架涉及的基本概念介绍:

关注点(concern):一个关注点可以是一个特定的问题、概念、或是应用程序的兴趣区间--总而言之,应用程序必须达到的一个目标。

核心关注点(core concern):业务功能模块,如:存款模块,取款模块,转账模块等,

横切关注点(crosscutting concern):非功能性的、横切性模块,如:安全性管理,事务管理,性能监控等。

方面(aspect):一个方面是对一个横切关注点的模块化,它将那些原本散落在各处的、用于实现这个关注点的代码归整到一处。

连接点(join point):程序执行过程中的一点,如:

字段访问:读、写实例变量;

方法调用:对方法(包括构造方法)的调用;

异常抛出:特定的异常被抛出。

切入点(pointcut):一组连接点的总称,用于指定某个增强应该在何时被调用。切入点常用正则表达式或别的通配符语法来描述,有些AOP实现技术还支持切入点的组合。

增强(advice):在特定连接点执行的动作。很多AOP框架都以拦截器(interceptor)的形式来表现增强--所谓拦截器是这样的一个

对象:当连接点被调用时,它会收到一个回调消息。基本的增强有:

前增强(BeforeAdvice):在连接点调用之前,首先调用增强;

后增强(AfterAdvice):在连接点调用之后,再调用增强,在AspectJ中,后增强又分为三种:

AfterReturningAdvice:在调用成功完成(没有异常抛出)之后。

AfterThrowingAdvice:在抛出某种特定类型(或其子类型)的异常之后。

AfterAdvice:在连接点的任何调用之后,不管调用是否抛出异常。

环绕增强(AroundAdvice):这类增强可以完全控制执行流程。除了完成本身的工作之外,它还需要负责主动调用连接点,促使真实的操作发生(proceed)-- 这通常是通过调用某个特定的方法来完成的。

引介(introduction):为一个现有的Java类或接口添加方法或字段。这种技术可以用于实现Java中的多继承,或者给现有对象模型附加新的API。

混入继承(mixin inheritance):一个"混入类"封装了一组功能,这组功能可以被"混入"到现有的类当中,并且无须使用传统的继承手段。在AOP这里,混入是通过引介来实现的。在Java语言中,可以通过混入来模拟多继承。

织入(weaving):将方面整合到完整的执行流程(或完整的类,此时被织入的便是引介中)。

拦截器(initerceptor):很多AOP框架用它来实现字段和方法的拦截(interception)。随之而来的就是在连接点(如方法拦截)处挂接一条拦截器链(interceptor chain),链条上的每个拦截器通常会调用下一个拦截器。

AOP代理(AOP proxy):即被增强(advise)的对象引用--也就是说,AOP增强将在其上执行的这样一个对象引用。

目标对象(target object):位于拦截器链末端的对象实例--这个概念只存在于那些使用了拦截机制的框架之中。

注:上述概念描述引自《Expert One-on-One J2EE Development without EJB》中第八章对AOP概念描述部分,更多精彩部分可以参阅本章的完整内容。

上述概念已被Spring AOP框架很好的实现,相关组件:

Advisor 组件,

Advice 组件,

Pointcut 组件,

Advised 组件,

AopProxy 组件,

AopProxyFactory 组件,

图1.

图1是对增强、切入点、方面、AOP代理之间依赖关系的全景图。

增强和切入点组成一个方面,方面信息与目标对象信息被组织到Advised中,AopProxyFactory通过Advised中保存的信息生成AopProxy

对象,调用AopProxy.getProxy()方法即可获得增强后的对象。

这里要着重了解的是不同的增强子类型,不同的切入点子类型,

对于不同的切入点子类型最重要的两种子类型:静态切入点,动态切入点,

静态切入点:根据部署阶段的信息选择增强,如"拦截特定类的所有getter方法";

动态切入点:根据运行时的信息选择增强,如"如果某方法的返回值为null,则将其纳入某切入点"。

图2.

图2是对图1中Advisor与Pointcut的实现细化,图中类之间的关系直观上有点乱,但细看下关系还是相当清晰的,

以Advisor结尾的是方面类型,以Pointcut结尾的是切入点类型,

Advisor与Pointcut的复用关系分两类:一类是组合复用,另一类是具体继承复用,

组合复用例子 如:RegexpMethodPointcutAdvisor 与 AbstractRegexpMethodPointcut之间的关系,

NameMatchMethodPointcutAdvisor 与 NameMatchMethodPointcut之间的关系,

具体继承复用例子 如:StaticMethodMatcherPointcutAdvisor 与 StaticMethodMatcherPointcut 之间的关系,

DynamicMethodMatcherPointcutAdvisor 与 DynamicMethodMatcherPointcut 之间的关系,

图3.

图3是对图1中生成AopProxy对象的实现细化,

AopProxyFactory通过AdvisedSupport提供的信息生成AopProxy对象,AopProxy对象的生成分两类方式:一类是动态代理,另一类是字节码增强;

需要注意的是,ProxyFactory与ProxyFactoryBean并不是功能实现的必要部分,主要目的为编程式使用代理提供便利的API。

下面是一个简单的sample:

//目标对象接口.  public interface Target {      public String play(int arg);  }  //目标对象实现.  public class TargetImpl implements Target {       public String play(int arg) {           System.out.println("play method....");          return "[Target:]" + arg;      }  }  //前置增强  public class MyBeforeAdvice implements MethodBeforeAdvice {      public void before(Method method, Object[] args, Object target)              throws Throwable {           System.out.println(method.getName());           System.out.println("before method!");      }  }  //后置增强  public class MyAfterAdvice implements AfterReturningAdvice {      public void afterReturning(Object returnValue, Method method,              Object[] args, Object target) throws Throwable {           System.out.println(returnValue + ":after method");       }  }  //切入点实现  public class MyPointcut implements Pointcut {       public ClassFilter getClassFilter() {                     return new ClassFilter() {               public boolean matches(Class arg0) {                  if (arg0 == TargetImpl.class) {                      return true;                  }                  return false;              }                        };      }       public MethodMatcher getMethodMatcher() {                     return new MethodMatcher() {               public boolean isRuntime() {                                     return false;              }               public boolean matches(Method arg0, Class arg1) {                                    if ("play".equals(arg0.getName())) {                      return true;                  }                  return false;              }               public boolean matches(Method arg0, Class arg1, Object[] arg2) {                  System.out.println("aaaaaa");                  if ("play".equals(arg0.getName())) {                      return true;                  }                  return false;              }                        };      }   }  public class Main {      public static void main(String[] args) {           Target target = new TargetImpl();   //目标对象           Advice beforeAdvice = new MyBeforeAdvice(); //增强           Pointcut pointcut = new MyPointcut(); //切入点           DefaultPointcutAdvisor dda = new DefaultPointcutAdvisor(); //切面           dda.setAdvice(beforeAdvice);           dda.setPointcut(pointcut);                      AdvisedSupport advisedSupport = new AdvisedSupport(); //提供基本的编程方式,           advisedSupport.addAdvisor(dda);           advisedSupport.addAdvice(new MyAfterAdvice());           advisedSupport.addInterface(Target.class);           advisedSupport.setTarget(target);           AopProxy aopProxy = new DefaultAopProxyFactory().createAopProxy(advisedSupport);           Target proxy = (Target)aopProxy.getProxy();           System.out.println(proxy.play(200));                      ProxyFactory proxyFactory = new ProxyFactory();  //提供便利的编程方式.           proxyFactory.addAdvisor(dda);           proxyFactory.addInterface(Target.class);           proxyFactory.setTarget(target);           Target proxy2 = (Target)proxyFactory.getProxy();           System.out.println(proxy2.play(201));                      ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); //提供便利的配置方式           proxyFactoryBean.addAdvisor(dda);           proxyFactoryBean.addInterface(Target.class);           proxyFactoryBean.setTarget(target);           Target proxy3 = (Target)proxyFactoryBean.getObject();           System.out.println(proxy3.play(232));      }  }

注:此处为了简单忽略了一些概念描述:

1.对引介,混入继承没有涉及。

2.对通知链的管理,如:同一切入点多个通知对象之间的执行顺序问题;

3.上述的描述是Spring AOP框架本身,所提供的使用方式是编程式,这种使用方式太过于低级,以至于我们在九成的情况下不会使用到,主流的使用方式是配置化的声明式使用方式,将AOP与IoC结合起来使用才能发挥出***威力,ProxyFactoryBean提供了有限的声明式使用方式,但严格来说它仍是编程式,因为ProxyFactoryBean是一个FactoryBean,一个FactoryBean的目标就是以编程式替换复杂的配置式,而且最重要的是它暴露的API太过低级,配置文件中bean元素的abstract属性对配置文件的长度提供有限的帮助,自动代DefaultAdvisorAutoProxyCreator很好的隐藏了低级的API,DefaultAdvisorAutoProxyCreator是一个BeanPostProcessor,用于完成AOP框架与IoC容器的集成工作,但是这种方式依然没有解决需要同XXXAdvisor这样的低级API打交道的问题;

随着spring2.x引入的xml元素及@Aspect注解的AspectJ描述性风格的出现,使用Spring AOP框架的使用达到完全的声明式标准,这种风格也使得Spring 事务框架受益,从TransactionProxyFactoryBean类到xml元素、 及@Transactional注解,

原文:http://www.iteye.com/topic/1114645

使得我们只需关注高层描述,而无需涉及低级API。

附上DefaultAdvisorAutoProxyCreator的类结构图:

总结:

要全面理解AOP相关概念,回答下述问题是必须的。

1。AOP概念产生的背景,AOP所要解决的问题,AOP所涉及的概念,

2。实现一个AOP框架所需要注意的问题是什么,

3。不同AOP框架实现之间的比较,

4。AOP的一些副作用讨论。

看完上述内容,你们掌握如何进行Spring AOP框架实现的结构分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

框架 对象 切入点 方法 概念 方式 之间 组件 连接点 方面 类型 问题 目标 拦截器 结构 信息 关注点 模块 部分 低级 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 山东特亿宝互联网科技有限公司 蓝思科技飞鸽互联网 互联网金融 科技金融 高科技与互联网 紫鲸互联网科技 时间互联网络科技 科技与互联网的利与弊 金融科技与互联网金融相同和不同 湖北码尼互联网科技有限公司电话 崇明区互联网教育科技诚信经营 未来五年的互联网科技 爱医互联网络科技 山东子淼互联网科技有限公司 沐思想互联网科技有限公司 21世纪互联网科技成就 新氧科技和美国互联网有关系吗 中国科技和美国互联网 好易买互联网科技 上海旺乐尼互联网科技有限公司 瑞安市蟠桃会互联网科技有限公司 精品咖啡豆 互联网加科技 华服互联网科技靠谱吗 互联网科技寓意 宁夏科技产业互联网案例 世界互联网科技公司市值排名 华夏互联网科技业 西安小鹰速贷互联网科技有限公司 山东子淼互联网科技有限公司 易租星互联网科技有限公司
0