Spring Aop分析
前言
上文讲述ioc框架的实现,本文开始讲述aop。在spring中aop也有3种配置方式,注解形式的我们先不讨论。我们先看看xml形式的配置方式。
<aop:config>
<aop:aspect ref="testInterceptor">
<aop:pointcut expression="execution(public * com.freud.test..*.*(..))"
id="testPointCut" />
<aop:after method="after" pointcut-ref="testPointCut" />
<aop:before method="before" pointcut-ref="testPointCut" />
</aop:aspect>
</aop:config>
<bean id="testInterceptor" class="com.freud.TestInterceptor" />
public class TestInterceptor { public void after() {
System.out.println("After");
} public void before() {
System.out.println("before");
}
}
上述配置是纯xml形式的配置,这样的配置结构清晰明了,就是看起来有点臃肿。
spring中提供了四种Advice用来支持对方法调用时施加的不同行为,通过这四种Advice可以帮助我们减少xml的配置
BeforeAdvice:具体接口:MethodBeforeAdvice 在目标方法调用之前调用的Advice
AfterAdvice:具体接口:AfterReturningAdvice 在目标方法调用并返回之后调用的Advice
AroundAdvice:具休接口:MethodInterceptor 在目标方法的整个执行前后有效,并且有能力控制目标方法的执行
ThrowsAdvice:具体接口:ThrowsAdvice 在目标方法抛出异常时调用的Advice
举个例子
<bean id="testInterceptor" class="com.freud.Interceptor.TestInterceptor"></bean>
<aop:config >
<!--切入点-->
<aop:pointcut id="testPointCut" expression="execution(public * com.freud.test.*.*(..))"/>
<!-- 在该切入点使用自定义拦截器 -->
<aop:advisor pointcut-ref="testPointCut" advice-ref="testInterceptor"/>
</aop:config>
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class TestInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//Do something before
Object ret = invocation.proceed();
//Do something After
return ret;
}
}
这里的TestInterceptor我们称之为Advice,就是往目标对象(Target)需要增强的内容。
这里MethodInvocation称之为切点(point cut),提供一组规则(使用 AspectJ pointcut expression language 来描述) 来匹配 程序中的方法(join point), 给满足规则的 程序中的方法 添加 Advice.
那么现在我们可以吧aop转变为两个问题
1.如何通过joinpoint匹配到特定的joinpoint
2.如何编写advice代码织入增强
接下来我们看下我们该如何实现上述问题
1.Aop简单实现
前面已经说到spring中提供了四种Advice,我们这里可以使用MethodInterceptor帮助我们实现aop
invoke的参数MethodInvocation参数暴露了被调用的方法; 目标连接点;AOP代理以及传递给方法的参数。
现在我们创建以下几个对象
1.TargetSource 被代理的对象
2.MethodInterceptor实现类
3.AdvisedSupport 封装TargetSource和MethodInterceptor
4.ReflectiveMethodInvocation 继承MethodInvocation
那现在一次调用就是这样
现在还有个问题就是要获取被代理的方法和参数。通过反射的方式可以取到,但是这样写起来不够灵活。这里采用动态代理
那么现在,实现aop的操作就很清晰了
2.Aop与Spring的集成
第一段我们将aop的织入过程进行分析,其中有个很重要的东西被我们忽略了。那就是Pointcut表达式。Spring借鉴了AspectJ表达式,封装成AspectJExpressionPointcut。这里不做过多介绍
本文最开始的时候介绍了xml的配置方式实现aop,第一段我们已代码的形式,实现了aop的织入。接下来 我们看下aop与spring是如何结合的。
spring提供了BeanPostProcessor对象,只要你的Bean实现了BeanPostProcessor
接口,那么Spring在初始化时,会优先找到它们,并且在Bean的初始化过程中,调用这个接口,从而实现对BeanFactory核心无侵入的扩展。
优先找到BeanPostProcessor代码如下
在实例化的时候,调用beanPostProcessor的方法增强bean。
我们举个例子
配置文件:
<bean id="autoProxyCreator" class="us.codecraft.tinyioc.aop.AspectJAwareAdvisorAutoProxyCreator"></bean> <bean id="timeInterceptor" class="us.codecraft.tinyioc.aop.TimerInterceptor"></bean> <bean id="aspectjAspect" class="us.codecraft.tinyioc.aop.AspectJExpressionPointcutAdvisor">
<property name="advice" ref="timeInterceptor"></property>
<property name="expression" value="execution(* us.codecraft.tinyioc.*.*(..))"></property>
</bean>
这里可能会有人奇怪这个配置为什么和最开头的配置不一样 ,最开头的配置都是以 <aop:config> 开头,而上面的配置文件只是几个bean而已。
其实spring在解析<aop:config>时会默认的提供包含 AspectJAwareAdvisorAutoProxyCreator 的 BeanDefinition,有兴趣的可以看看(org.springframework.aop.config.AopNamespaceUtils#registerAspectJAutoProxyCreatorIfNecessary)
在解析<aop:before>和<aop:after>时,spring会向候选Advisor链的开头添加一个org.springframework.aop.support.DefaultPointcutAdvisor。所以上述两种配置理论上是一样的。只是现在我们还没有spring解析的那一套代码,所以就直接已bean的形式写成配置文件。
测试代码
初始化的时候优先找到BeanPostProcessor上面已经提过了。getBean的前半段代码也已经提过,我们主要看下beanPostProcessor是如何增强的。
到这里,一个aop框架已经描述完毕了。
Spring Aop分析的更多相关文章
- Spring AOP分析(1) -- 基本概念
AOP全称是Aspect Oriented Programming,面向切面编程,是面向对象编程(OOP:Object Oriented Programming)的补充和完善.一般在系统中,OOP利用 ...
- Spring AOP分析(2) -- JdkDynamicAopProxy实现AOP
上文介绍了代理类是由默认AOP代理工厂DefaultAopProxyFactory中createAopProxy方法产生的.如果代理对象是接口类型,则生成JdkDynamicAopProxy代理:否则 ...
- Spring AOP分析(3) -- CglibAopProxy实现AOP
上文探讨了应用JDK动态代理实现Spring AOP功能的方式,下面将继续探讨Spring AOP功能的另外一种实现方式 -- CGLIB. 首先,来看看类名CglibAopProxy,该类实现了两个 ...
- (转)Spring AOP实现方式(转)
我们可以通过三种方式来使用Spring AOP,它们分别是:@Aspect-based(Annotation),Schema-based(XML),以及底层的Spring AOP API 底层的Spr ...
- 关于 Spring AOP (AspectJ) 该知晓的一切
关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上 ...
- spring aop两种配置方式
基于注解的Spring AOP开发 简单案例快速入门 定义目标类接口和实现类 /** * Created by zejian on 2017/2/19.*/ //接口类 public interfac ...
- 关于 Spring AOP (AspectJ) 你该知晓的一切
版权声明:本文为CSDN博主「zejian_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/javazej ...
- Spring AOP在函数接口调用性能分析及其日志处理方面的应用
面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...
- 161220、使用Spring AOP实现MySQL数据库读写分离案例分析
一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...
随机推荐
- 计算机爱好者协会技术贴markdown第三期
之前都是给大家展示的对文本的基本操作,这一期我们要给大家展示的就是很高大上的东西了哦 看左边是不是超low,右边是不是瞬间高大上了!!! 一个简单的表格是这么创建的: 爱酱 | Value - ...
- 我的Unity学习笔记之——Unity中从网站下载ab资源+下载存储一条龙
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Net ...
- eclipse 无法记住svn密码
每次要求输入密码,很恼人.经过一番折腾,在stackoverflow上找到了解决方案,上面大神果然多 简单的说,就是通过查看工作空间的日志文件,发现报了个java异常,缺少一个class文件(org. ...
- Java WebService 简单实例使用JDK
原文地址:http://www.cnblogs.com/jasoncc/archive/2011/12/22/2296052.html 什么是WebServices? 它是一种构建应用程序的普 ...
- 记录做一个类似于探探的卡片式布局的Recycleview有数据一直不显示
使用了别人的项目 https://github.com/JerryChan123/ReSwipeCard/blob/master/README_zh.md 之前找recycleview有数据不显示的原 ...
- 配置wildfly10为linux的服务,并开机启动
1.在opt路径下 下载 wildfly ,并解压下载下的压缩包 cd /opt sudo wget -c http://download.jboss.org/wildfly/10.0.0.Final ...
- HTML5结构标签
<!DOCTYPE html> <!-- ↑ 文档声明.HTML5已经简化为上述样式! 注意:文档声明必须有!而且必须在文档页面的第一行! HTML4.01之前的文档声明: &l ...
- 快乐python 零基础也能P图 —— PIL库
Python PIL PIL (Python Image Library) 库是Python 语言的一个第三方库,PIL库支持图像存储.显示和处理,能够处理几乎所有格式的图片. 一.PIL库简介 1. ...
- JavaScript基础整理
在HTML页面中嵌入JavaScript代码的三种方式 1.内嵌 写在<head>标签或<body>标签中 <script> function displayTim ...
- G++与C++的区别
C++是一门计算机编程语言,G++不是语言,是一款编译器中编译C++程序的命令而已. 不同的编译器,会对代码做出一些不同的优化 比如说: a++; 和 ++a; 如果从标准C的角度去理解.a++这个 ...