spring AOP的概念
1、Spring AOP中的几个基本概念:
- 切面(Aspect):切面就是一个关注点的模块化,如事务管理、日志管理、权限管理等;
- 连接点(Joinpoint):程序执行时的某个特定的点,在Spring中就是一个方法的执行;
- 通知(Advice):通知就是在切面的某个连接点上执行的操作,也就是事务管理、日志管理等;
- 切入点(Pointcut):切入点就是描述某一类选定的连接点,也就是指定某一类要织入通知的方法;
- 目标对象(Target):就是被AOP动态代理的目标对象;
2、设计分析
Spring AOP 的核心技术是JDK的动态代理技术(参考:JDK动态代理 一文)。
Spring Aop 生效需要经过一系列的操作,首先要为目标对象建立代理对象(接口是JDK代理实现,类是第三方CGLIB 来完成),然后启动代理对象的拦截器来完成切面的织入(通过一系列的适配器来实现的)。
3、应用场景
日志功能、权限校验、以及事物处理。
AopProxy代理对象

- ProxyConfig 为ProxyFactoryBean等子类提供配置属性
- AdvisedSupport 封装了AOP对通知和通知器的相关操作
- ProxyCreatorSupport 提供AopProxyFactory的操作权限
- AspectJProxyFactory 集成Spring和Aspect
- ProxyFactoryBean AOP功能封装,可在IOC容器中声明时配置
- ProxyFactory 需要编程式使用AOP功能
配置ProxyFactoryBean
|
|
|
|
我们可以从上面的代码中看到aopService对象注入的是生成的代理对象aopServiceProxy
详细代码可参考spring-aop demo
ProxyFactoryBean生成AopProxy代理对象
ProxyFactoryBean 需要为target对象生成Proxy代理对象;对ProxyFactoryBean而言,需要对target目标对象的增强处理(添加Advice)需要通过getObject方法包装。
|
|
下面看一下初始化通知器链的initializeAdvisorChain方法,
通知器链初始化完成之后,返回Sngleton的代理对象
|
|
下面我们详细看一下代理对象是如何生成的
|
|
代理对象是aopProxy生成,aopProxy又由ProxyFactory生成,aopProxyFactory是由ProxyFactoryBean的父类ProxyCreatorSupport生成,是在ProxyCreatorSupport的构造函数中默认生成DefaultAopProxyFactory对象,也就是说代理对象是在DefaultAopProxyFactory中生成。
|
|
下面看一下DefaultAopProxyFactory的源码,当代理对象是接口(并且不是SpringProxy接口)的话使用JDK动态代理(JdkDynamicAopProxy),否则的话使用CGLIB代理(CglibAopProxy)。
|
|
获取代理对象,并执行目标对象的方法
现在我们得到了aopProxy对象,下面就可以获取代理对象了,下面我们看一下JdkDynamicAopProxy代码,
其实到这里我们可以发现JdkDynamicAopProxy的作用等于动态代理DEMO中的DynamicProxyHandler,
JdkDynamicAopProxy实现了InvocationHandler的invoke方法,改方法做为代理对象Proxy的回调函数被调用,因此在invoke中完成对目标对象的拦截(增强操作)。
|
|
目标对象方法调用
如果没有设置拦截器,直接对目标对象的方法进行调用,JdkDynamicAopProxy代理的对象通过反射机制在AopUtils.invokeJoinpointUsingReflection方法中实现。
|
|
拦截器方法调用
不管是JDK代理还是CGLIB代理,拦截器的调用都是通过ReflectiveMethodInvocation来实现的,在proceed方法中调用拦截器方法:
|
|
到这里,我们已经知道拦截器和目标对象的方法被调用的过程了。
拦截器链的生成
在JdkDynamicAopProxy的invoke中获取拦截器链进行操作,下面我们看一下拦截器是怎么生成的:
AdvisedSupport 取得拦截器
|
|
从上面的代码片段我们可知,拦截器被(cache)缓存,下面看一下DefaultAdvisorChainFactory中拦截器具体注册的过程
|
|
下面是DefaultAdvisorAdapterRegistry中获取拦截器的代码
到这里整个过程就一目了然了,在我看来Spring AOP 功能的实现就是通过及适配器设计模式把增强操作组装成一个拦截器,再在通过动态代理的方式调用目标方法的过程中执行相应的拦截器从而完成了增强操作。
示例代码https://github.com/lili1990/learning/tree/master/spring-aop/spring-aop-demo