Spring-AOP模式

        AOP是什么?有人说AOP叫切面编程,也有人说AOP是框架。实际上AOP就是单纯的一种设计模式,软件设计的一种思路。那么AOP能带来什么好处呢?或者说遇到什么问题的时候可以采用这种软件设计思路来解决问题。Spring-AOP在jdk5版本之前采用的是自己实现AOP概念中对应的接口(Spring揭秘称该方式为AOP一代),等到了jdk5版本以后采用注解的方式不需要自己实现接口(Spring揭秘称该方式为AOP二代,该方式也是当下主流方式)。但是注解方式的AOP不管是如何的方便,它的实现底层逻辑还是与接口方式的AOP保持一致的。

        AOP的应用场景数据缓存、捕获异常输出日志、数据访问控制等,这些场景有一个共同的特征即程序内不同功能都会有可能用到缓存、异常日志输出、权限访问控制,这些场景对于程序功能来说是共性问题。就好比一个功能插件,要用的时候调用下,不用的时候不调用就好了。那么写程序过程中遇到重复性代码的时候是不是就可以考虑AOP这种设计模式。

        AOP叫切面编程是不是很难理解,谁又能知道它是个什么东西。如果说AOP就是在一定条件下,运行过程中将代码逻辑(也可称横切逻辑)加入到(织入)原代码逻辑中,这样就比较具象化了。这种设计叹为观止,程序执行的情况下,在原来的代码逻辑中新加逻辑进去。服气服气!

        既然是往原来的逻辑中加逻辑,那么横切逻辑写在什么地方,加入的时机或者说加入的条件是什么,又是在原先逻辑的什么地方加入呢。这种设计方式实现的原理又是什么呢?

满足什么条件,在什么地方,加入什么东西就是AOP的整个操作流程

  1. Advice横切逻辑对标需要动态新增的代码逻辑
  2. JoinPoint对标能进行织入操作的位置,实际上AOP设计来说JoinPoint非常的多设计属性获取、属性设置、方法调用、方法执行、构造方法、静态代码块都属于能够进行织入的地方,但是Spring只是想了方法执行这个地方的横切逻辑织入
  3. PointCut通过表达式捕获对象,对满足表达式的对象进行织入操作

        以上是AOP软件设计中比较核心的一些概念,那么Spring AOP一代(接口方式AOP)是如何来实现呢?Spring有一个Advisor类,该类将Advice横切逻辑与PointCut捕获表达式全部封装在Advisor中,根据Advice或者PointCut类型的不同,产生了不同的Advisor。

Advice类型
Advice类型说明
BeforceAdvice方法执行前织入的横切逻辑,常用做资源初始化场景
ThrowAdvice方法执行异常时织入的横切逻辑
AfterReturingAdvice方法运行结束时织入的横切逻辑
MethodInterceptor方法运行前、方法运行结束时织入的横切逻辑使用场景最广比如性能监测、日志记录、安全检查
Introduction比较特殊为特定的用户对象进行织入的横切逻辑

PointCut
PointCut类型说明(捕获特定的方法,对捕获到的方法进行织入操作)
NameMachMethodPointCut根据方法名称来捕获对象方法
JdkRegexpMethodPointCut正则匹配的方式捕获对象方法
Perl5RegexpMethodPointCut正则匹配的方式捕获对象方法
ClassFilter捕获对象中的所有方法
ComposablePointCut将对象方法结果进行交、并运算产生新的需要织入的集合
ControlFlowPointCut特定对象调用指定方法时,才能成功捕获对应方法
AnnotationMachingPointCut注解形式的捕获表达式
自定义类型PointCut根据需求自定的表达式
Advisor与Advice/PointCut对应关系
Advisor类型Advice类型PointCut类型
DefaultPointCutAdvisor非Introduction所有
NameMachMethodPointCutAdvisor非IntroductionNameMachMethodPointCut
RegexpMethodPointCutAdvisor非Introduction正则类型
IntroductionAdvisorIntroductionClassFilter类型
DefaultBeanFactoryPointCutAdvisor非Introduction所有

               AOP的横切逻辑有了,织入的位置有了,剩下织入器了,ProxyFactory。Spring的织入器采用的是代理模式+动态字节码的方式共同完成织入操作的。代理方式采用的是动态生产一个代理类,将原对象传递到代理对象中,接着将横切逻辑织入代理对象中,调用代理对象的方法完成织入操作的这么一个过程。但是代理方式有了为什么还要一个动态字节码的方式呢,这是因为代理方式有一个要求,需要进行织入的对象需要提供一个接口,没有接口的对象是无法使用代理方式的。故采用动态字节码的方式来实现织入。动态字节码实际上就是将原类进行了继承,基于原类产生一个子类,在子类中将横切逻辑织入进去。所以Spring的织入器实际上代理与动态字节码互相配合来是想织入操作的。

        AOP二代(注解AOP),在了解完AOP一代对应的概念以后,AOP二代上手就非常的快。主要也就是了解注解的作用,与上一代各概念互相对应。

AOP二代注解
注解类型对标一代概念备注
@AspectAdvisor
@PointCut("pointcut表达式")PointCut@PointCut注解可以加表达式,通过表达式捕获对应的目标对象各个方法,从而为后续的织入做准备
@args(Class类型)PointCut@args会检查方法中的参数,匹配参数类型,如果方法参数类型与注解描述的类型匹配上,那么该方法会被捕获
@within(Class类型)PointCut检查对象类型,匹配上捕获对象所有方法
@this(Class类型/接口类型)、@target(Class类型/接口类型)PointCut检查对象类型,匹配上捕获对象所有方法
@annotation(注解名称)PointCut检查方法上的注解名称与注解描述上的注解名称匹配,捕获该方法
@BeforeAdvice方法执行前执行的横切逻辑
@AfterReturingAdvice方法执行成功后执行的横切逻辑
@AfterThrowingAdvice方法执行异常后执行的横切逻辑
@AroundAdvice可以自己决定原逻辑放在横切逻辑的位置,是放在横切逻辑前还是横切逻辑后
@DeclareParentsAdvice对标Introduction类型的Advice

实际上在笔者看来,进行AOP织入操作的结果与装饰器模式非常的像,达到的效果不就是改造了原来的方法,在原来的方法上进行了改造,额外添加了逻辑上去

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值