前言


上文讲述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分析的更多相关文章

  1. Spring AOP分析(1) -- 基本概念

    AOP全称是Aspect Oriented Programming,面向切面编程,是面向对象编程(OOP:Object Oriented Programming)的补充和完善.一般在系统中,OOP利用 ...

  2. Spring AOP分析(2) -- JdkDynamicAopProxy实现AOP

    上文介绍了代理类是由默认AOP代理工厂DefaultAopProxyFactory中createAopProxy方法产生的.如果代理对象是接口类型,则生成JdkDynamicAopProxy代理:否则 ...

  3. Spring AOP分析(3) -- CglibAopProxy实现AOP

    上文探讨了应用JDK动态代理实现Spring AOP功能的方式,下面将继续探讨Spring AOP功能的另外一种实现方式 -- CGLIB. 首先,来看看类名CglibAopProxy,该类实现了两个 ...

  4. (转)Spring AOP实现方式(转)

    我们可以通过三种方式来使用Spring AOP,它们分别是:@Aspect-based(Annotation),Schema-based(XML),以及底层的Spring AOP API 底层的Spr ...

  5. 关于 Spring AOP (AspectJ) 该知晓的一切

    关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上 ...

  6. spring aop两种配置方式

    基于注解的Spring AOP开发 简单案例快速入门 定义目标类接口和实现类 /** * Created by zejian on 2017/2/19.*/ //接口类 public interfac ...

  7. 关于 Spring AOP (AspectJ) 你该知晓的一切

    版权声明:本文为CSDN博主「zejian_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/javazej ...

  8. Spring AOP在函数接口调用性能分析及其日志处理方面的应用

    面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...

  9. 161220、使用Spring AOP实现MySQL数据库读写分离案例分析

    一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...

随机推荐

  1. git的使用方式总结

    1.先用 git clone url 克隆下来项目 2.查看下载的项目里面有没有一个名字叫git的文件夹 3.用git branch查看当前所有的本地分支,绿色的代表当前所处的分支 4.若本地只有一个 ...

  2. 20155312 张竞予 Exp2 后门原理与实践

    Exp2 后门原理与实践 目录 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? (2)例举你知道的后门如何启动起来(win及linux)的方式? (3)Meterpreter有哪 ...

  3. python第三天基础之字符编码

    一 了解字符编码的知识储备 1. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的, ...

  4. 20175316盛茂淞 2018-2019-2 《Java程序设计》第9周学习总结

    20175316盛茂淞 2018-2019-2 <Java程序设计>第9周学习总结 教材学习内容总结 下载安装MySQL数据库管理系统. 学习<Java程序设计>第十一章MyS ...

  5. 01 C语言程序设计--01 C语言基础--第1章 C语言概述&第2章 GCC和GDB

    走进嵌入式开发的世界,企业级项目课程让你达到企业嵌入式应用开发要求.名师在线答疑,解决疑难.科学评测体系,系统评估学习.核心项目实........ 30 门课程 241小时12分钟 824 人学习 学 ...

  6. vue公共

    1 需求:在做项目的过程中发现,有一些功能是公共的,于是就想把这些公共的功能抽出来,做成独立的模块,别的项目需要用到,直接引用这个模块 2 问题: 前端:1 是用vue做的,vue的跳转是通过rout ...

  7. 2019浙江省赛K zoj4110 Strings in the Pocket(manachar)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 题意 给你两个串,可以翻转a串的一个区间,问有多少对l,r使得翻转后的a ...

  8. restful状态码常用

    在进行后端接口API封装的过程中,需要考虑各种错误信息的输出.一般情况下,根据相应问题输出适合的HTTP状态码,可以方便前端快速定位错误,减少沟通成本. HTTP状态码有很多,每个都有对应的含义,下面 ...

  9. 20155326《网络对抗》Web安全基础实践

    20155326<网络对抗>Web安全基础实践 实验后回答的问题 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是在Web应用对后台数据库查询语句处理存在的安全漏洞,通过构建特殊 ...

  10. yield(),wait(),sleep(),join()

    yield(),wait(),sleep(),join()yield()虽然可以让线程由“运行状态”进入到“就绪状态”:但是,它不一定会让其它线程获取CPU执行权(即,其它线程进入到“运行状态”),即 ...