AOP有些特有的概念,如:advisor、advice和pointcut等等,使用或配置起来有点绕,让人感觉有些距离感,其实它的实现就是一组标准的设计模式的组合使用:Factory、Proxy、Chain of Responsibility,只要搞清楚这几个设计模式,读AOP的源码是比较容易的。
首先看看ProxyFactoryBean这个类,这是AOP使用的入口,从AOP拿到的bean object就是ProxyFactoryBean.getObject得到的,从这条线下去,发现AOP就是通过Proxy模式从实际要执行的target做了包装,而Proxy还不止一套方案,通过Factory封装了两套Proxy实现方案:JDK 动态Proxy和Cglib Proxy。有两套实现主要是因为JDK 动态Proxy必须要target实现某个接口,如果不满足这个条件就会用Cglib增强字节码的方式来实现proxy。
就拿JDK Proxy为例,Spring AOP使用了标准的JDK提供的动态Proxy方案,我们先看看标准的动态Proxy是什么样子,看下面类图:

Cilent通过Proxy.newProxyInstance(classLoader, proxiedInterfaces, invocationHandler);就能拿到target的proxy object,在执行target的方法时就会先执行到DynamicProxy中的invoke方法从而实现代理包装。基于这个道理来看Spring AOP的实现,实际上就是标准地基于这个方式来做的,Spring AOP的所有花招都体现在JdkDynamicAopProxy.invoke中(当然在Cglib中是通过callback来做的,道理类似)。
通过看JdkDynamicAopProxy.invoke的源码会发现,Spring AOP的各种花招是通过Chain of Responsibility模式串起来的,先看看一个标准的Chain of Responsibility是什么样子,看下面的类图:

而Chain of Responsibility的关键在于Invocation与Interceptor的配合,主要原则就两条:
1)Invocation需要维护Interceptor集合和游标,每次调用invoke时需要先调用游标所在的Interceptor.invoke,如果游标已超过最后一个Interceptor,则调用实际target的方法
2)Interceptor的invoke中除了要执行自己的拦截逻辑,还要通过Invocation.invoke把调用传递下去,拦截的灵活性就体现在Invocation.invoke执行与否和执行的顺序。
以上逻辑通过时序图来看,如下图所示:

理解Chain of Responsibility后再来看Spring AOP,JdkDynamicAopProxy.invoke做的事情就是以上Client做的事情,
1)首先通过this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);组装interceptor chain
2)然后new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);得到invocation
3)最后通过invocation.proceed();启动责任链
而Spring AOP的那些概念都体现在组装interceptor chain中,advisor、advice和pointcut无非就是帮助你描述如何对Target进行拦截,对这一块感兴趣的朋友可以好好读读里面的代码。另外,Spring AOP提供了各种各样的Interceptor,来实现各种形式的横切,具体做法可以详细看看各Interceptor的实现。
综上所述,整个流程如下图所示:

总之,把握了Factory、Proxy、Chain of Responsibility的运用也就把握了Spring AOP的实现原理,道理虽然简单,但其中的精髓和原由还是值得我们继续深思的。
分享到:
相关推荐
Spring Framework Master分支则意味着这个压缩包包含了Spring框架的最新源码,开发者可以深入研究其内部机制,进行二次开发或者学习Spring的设计思想。 总的来说,"spring-aop-4.2.6.RELEASE.zip"及其关联的"spring...
47 Spring源码阅读 AOP - CreateProxy - buildAdvisor.mp4 48 Spring源码阅读 AOP - CreateProxy - getProxy.mp4 49 Spring源码中的常见的设计模式 - 桥接模式与工厂模式的配合.mp4 50 Spring源码中的常见的设计...
在深入学习和分析Spring源码时,有时我们需要一个完整的运行环境来理解其内部机制。"spring-cglib-repack-3.2.5.jar"、"spring-objenesis-repack-2.6.jar"和"spring-objenesis-repack-2.5.1.jar"这三个文件是Spring...
【Spring源码篇 03】Spring源码手写篇-手写AOP Spring框架是Java开发中广泛使用的轻量级容器,它的核心特性之一就是面向切面编程(Aspect-Oriented Programming,简称AOP)。AOP允许程序员定义“横切关注点”,即...
47 Spring源码阅读 AOP - CreateProxy - buildAdvisor.mp4 48 Spring源码阅读 AOP - CreateProxy - getProxy.mp4 49 Spring源码中的常见的设计模式 - 桥接模式与工厂模式的配合.mp4 50 Spring源码中的常见的设计...
47 Spring源码阅读 AOP - CreateProxy - buildAdvisor.mp4 48 Spring源码阅读 AOP - CreateProxy - getProxy.mp4 49 Spring源码中的常见的设计模式 - 桥接模式与工厂模式的配合.mp4 50 Spring源码中的常见的设计...
47 Spring源码阅读 AOP - CreateProxy - buildAdvisor.mp4 48 Spring源码阅读 AOP - CreateProxy - getProxy.mp4 49 Spring源码中的常见的设计模式 - 桥接模式与工厂模式的配合.mp4 50 Spring源码中的常见的设计...
在2022年8月14日更新的Spring源码中,我们可以深入理解其设计理念和实现机制。 Spring框架的主要组成部分包括: 1. **核心容器**:这是Spring的基础,主要包括BeanFactory和ApplicationContext。BeanFactory负责...
《深入剖析Spring AOP源码》 Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对现有代码进行功能增强的技术。本文将深入探讨Spring ...
Spring Framework 是一个广泛使用的Java应用开发框架,由Pivotal ...通过研究源码,你可以学习如何实现DI、AOP,以及Spring如何处理数据库操作和Web请求。这对于提升你的Java开发技能和理解软件设计原则非常有帮助。
总结来说,"my-spring.rar-Spring-AOP源码Demo"提供了学习和研究Spring AOP的实例,涵盖了切面、通知、切入点等核心概念,通过分析源码,开发者能够深入理解Spring AOP的工作机制,并能将其应用于实际的项目开发中。
在编译Spring源码时,如果缺少这些依赖,会导致编译失败或功能不完整。因此,确保这两个jar包的正确引入对于理解和构建Spring源码是至关重要的。 在实际项目中,通常我们会通过Maven或Gradle等构建工具管理这些依赖...
官方源码的发布意味着开发者可以直接查看和学习Spring的实现细节,这对于理解和定制框架非常有帮助。Spring有着庞大的社区和丰富的教程资源,使得开发者能够迅速解决问题和学习新技术。 综上所述,Spring ...
死磕spring源码系列-SpringAop十分钟快速入门
死磕spring源码系列-深度解析spring_aop
《Spring框架5.3.29深度...通过深入学习和理解Spring 5.3.29的源码,开发者可以更好地利用其特性,编写出高效、灵活的Java应用。同时,掌握Spring框架的核心原理也有助于开发者在解决实际问题时更有针对性和创造性。
在本"Spring-AOP源码Demo"中,我们将深入探讨Spring AOP的工作原理以及如何通过源码学习其核心概念。 1. **AOP的基本概念** - **切面(Aspect)**:AOP的核心单元,它封装了横切关注点,包括通知(advice)、切入...
spring-webmvc-5.0.9.RELEASE-sources.jar则包含了源码,可以深入研究Spring Web MVC的实现细节,对于学习和调试都非常有帮助。 九、依赖管理 在实际项目中,Spring Web MVC往往与其他Spring模块如Core、AOP、Data...
Spring的源码结构清晰,模块划分明确,主要分为Core Container、Data Access/Integration、Web、AOP(面向切面编程)、Instrumentation、Test等核心模块。在Core Container中,主要包括ApplicationContext和Bean工厂...
标题“spring-aop-aspectj-case”涉及到的是Spring框架中的AOP(面向切面编程)与AspectJ的集成使用案例。在Spring框架中,AOP用于处理系统中的横切关注点,如日志、事务管理等,而AspectJ则是一个强大的、独立的...