您的位置:首页 > 编程语言 > Java开发

Spring AOP基础

2017-02-16 21:01 169 查看
基础部分各类通知的应用源码testSpring参照链接(https://github.com/TerenceJIng/javaLearn

一 什么是AOP级实现方式

AOP:Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术。

主要功能是:日志记录,性能统计,安全控制,事物处理,异常处理等。

切面和功能是垂直的,不同事物在某一个切面时间点有共同的逻辑处理,则可以将这些剖面的处理抽离出来统一维护,开发者不需要知道这些处理,对于这种统一维护技术,面向开发者是透明的,开发者能够统一维护某些共同的处理逻辑,提高效率。

二 基本概念

切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。

连接点(Joinpoint):程序执行过程中的某个特定的点

通知(Advice):在切面的某个特定的连接点上执行的动作

切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联

引入(Introduction):在不修改类代码的前提下,为类添加新的方法和属性(动态修改class文件)

目标对象(TargetObject):被一个或者多个切面所通知的对象

AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)

织入(Weaving):把切面连接到其他的应有个程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入

Advice通知类型

前置通知(Beforeadvice):在某个连接点之前的通知,但是不能阻止连接前的执行
返回后通知(Afterreturning advice):在某个连接点(Jointpoint)正常完成后执行的通知
抛出异常通知(Afterthrowing advice):在方法抛出异常退出时执行的通知
后通知(After(finally)advice):当某连接点退出的时候执行的通知(不论是正常返回,还是异常退出)
环绕通知(AdroundAdvice)包围一个连接点(jointpoint)的通知

三 Spring中的AOP

1 Spring框架中AOP的作用

1、提供了声明式的企业服务,特别是EJB的替代服务的声明,当然,Spring AOP不仅仅局限于企业服务,AOP可以实现任何服务的业务切面,达到某种目的

2、允许用户定制自己的方面,以完成OOP与AOP的互补使用。在这里需要说一下,AOP是指在各个功能上横切的功能,OOP是面向对象编程,模拟真实世界的行为方式,可以认为是实现一个功能的顺序,两者之间可以互补使用。

2 Spring 的AOP的实现

1、 纯Java实现,无需特殊的编译过程,不需要控制类加载器层次。

2、 目前只支持方法连接点(通知Spring Bean的方法执行)

3、 不是为了提供最完成的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和SpringIOC容器之间的整合,用于帮助解决企业应用、互联网应用开发中常见的问题。

4、SpringAOP不会与AspectJ竞争,从而提供综合全面的AOP解决方案。AspectJ本身就是一个完整全面综合的解决方案。

3 有无接口的Spring AOP实现区别

1、 有接口:Spring AOP默认使用标准的Java SE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理。

2、 无接口:Spring AOP中也可以使用CGLIB代理,(如果一个业务对象并灭有实现一个接口)

四 Schema-based AOP

1 切面Aspect和通知器Advice

基于配置的Spring AOP的应用中,Spring所有的切面和通知器都必须放在一个<aop:config>内,可以配置多个<aop:config>,每个<aop:config>下可以包含pointcut/advisor/aspect元素,但是这些元素是有序的,不能打乱。<aop:config>风格的配置大量使用了Spring的自动代理机制。

配置示例:



2 配置切入点pointcut

以下的东西不用记,使用过程查阅即可:









完整的配置示例:

<aop:config>
<aop:aspect id="terenceAspectAOP"ref="terenceAspect">

<!--   配置aop切面切入点pointcut;* com之间必须加入空格-->
<aop:pointcut expression="execution(*com.terence.aop.schema.advice.biz.*Biz.*(..))"id="terencePointcut"/>
<!--配置前置通知-->
<aop:before method="before" pointcut-ref="terencePointcut"/> </aop:aspect>
</aop:config>


3 Introductions

简介允许一个切面声明一个实现指定接口的通知对象,并且提供了一个接口实现类来代表这些对象。

所有基于配置文件的切面(schema defined aspects)只支持单例(singleton model)

用<aop:declare-parents>元素声明该元素,用于声明所匹配的类型拥有一个新的parent类;

<aop:declare-parents
types-matching="com.terence.aop.schema.advice.biz.*(..)"
implement-interface="com.terence.aop.schema.advice.Fit"
default-impl="com.terence.aop.schema.advice.FitImpl"/>


测试代码:

@Test
public void testFit()
{
Fit fit=(Fit)super.getBean("aspectBiz");
fit.filter();
}

上述简介匹配理解思路:测试类,利用getBean(beanID)方法获取了type-matching下的匹配到的AspectBiz对象,将其强制转化为Fit接口,即为重新获取的Bean对象强行指定了个父类实现接口,然后可以调用该接口的实现方法。结合Introductions的作用,就是允许FitImpl这个实现类来代表AspectBiz对象;

通俗的讲,这是一种解耦现象,一个业务类(AspectBiz)在做自己的工作的时候,还能莫名其妙的享受一些多余的功能而不用做多余的工作,手段途径就是通过给匹配到的类重新指定一个父类实现接口,然后调用该接口的实现类中的方法。

一句话总结:Introductions给业务类的切面类引入了来自第三方的现成行为而不用付出代价。

4 Advisors

Advisor就像一个小的自包含的方面,只有一个advice。
切面自身通过一个bean表示,并且必须实现某个advice接口,同时,advisor也可以很好的利用AspectJ的切入表达式。
Spring通过配置文件中的<aop:advisor>元素支持advisor实际使用中,大多数情况下它会和transcational advice配合使用。
为了定义一个advisor的优先级以便让advice可以有序,可以使用order属性来定义advisor的顺序。

适用于:统计调用次数,比如验证用户,验证三次之后不允许在验证了,可以抛出异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息