Spring AOP学习笔记

  1. AOP(Aspect-Oriented Programming):

    面向切面编程。通过预编译方式和运行期动态代理程序功能的统一维护技术。AOP是OOP的延续,是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开放效率。

    AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码。

    AOP主要编程对象是切面(aspect),即横切关注点的方法

    AOP使业务模块更简洁,只包含核心业务代码

  2. 专业术语
    1. Joinpoint(连接点):程序执行的某个特定位置,如某个方法的调用前、后、抛出异常后等,在Spring中,只支持方法类型的连接点
    2. Pointcut(切点):每个类都拥有多个Joinpoint,切入点就是我们要对哪些Joinpoint进行拦截,在Spring中,指定Pointcut相当于指定Joinpoint的查询条件
      ,切入点通过org.foramework.aop.Pointcut接口进行描述,它使用类和方法作为Joinpoint的查询条件
    3. Advice(通知/增强):拦截到Joinpoint后要做的事情,在Spring中,就是方法的内容。通知分为前置增强、后置增强、异常增强,环绕增强,分别表示通知是在Joinpoint的什么位置。(切面要完成的功能和在连接点的什么方位完成)
    4. Introduction(引介):一种特殊的Advice,在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field(动态代理,JDK、CGLIB)
    5. Target(目标对象):代理的目标对象,即被横向抽取的业务逻辑对象
    6. Weaving(织入):把Advice(增强)应用到目标对象来创建代理对象的过程
    7. Proxy(代理):一个类被织入增强过后,产生的结果代理类Aspect(切面):是切入点和通知的结合
    8. 切面(Aspect):切面由Pointcut和Advice组成,它竟包括横切逻辑的定义,也包括Joinpoint的定义。Spring AOP(AspectJ)就是负责实施切面的框架,它将切面所定义的横切逻辑织入切面所指定的连接点
  3. 基于注解方式创建Aspect:
    1. @Aspect:表示被注解的类是个切面,切面首先是一个IOC容器中的Bean
    2. @Befor:被标识的通知为前置通知,在目标对象的JointPoint被执行时第一个调用
    3. @AfterReturning:被标识的通知为返回通知,在方法正常返回结果后调用。[returning]属性可指定返回值传入通知的参数名。如果方法抛出异常则不会调用返回通知。返回通知可以访问到方法的返回值
    4. @AfterThrowing:被标识的通知为异常通知,在方法抛出异常后条用。[throwing]属性可指定异常传入通知的参数名。该通知可以访问到方法抛出的异常
    5. @After:被标识的通知为后置通知,方法执行结束后调用,如果方法抛出异常,也会调用后置通知。因为方法可能抛出异常,所以无法访问方法的返回值
    6. @Aroud:被标识的通知为环绕通知,通知必须携带ProceedingJoinPoint参数,并且返回值类型必须是连接点的返回值类型。可以通过ProceedingJoinPoint.proceed()方法决定是否执行连接点
    7. @Pointcut:通过标识在方法上来申明一个切点表达式。通过value参数指定要声明的表达式,其他通知重用只需引用方法名作为切点表达式即可。一般被声明为切点的方法内部无任何操作

    //声明切点表达式

    @Pointcut(“execution(* com.andy.springtest.aop.UserService.*(..))”)

public void pointcutUserService (){}

//前置通知引用切点表达式

@Before(“pointcutUserService ()”)

public void beforeAdviceLog(){}

通知执行顺序:Aroud->Befor(如果在Aroud里没有调用proceed则不执行)->After->AfterReturning(如果抛异常则不执行)->AfterThrowin(如果不抛异常或者没有接受到对应参数的异常则不执行)

使用注解方式创建Aspect必须在spring容器配置文件中声明<aop:aspectj-autoproxy/>元素,使容器自动为AspectJ的注解的类生成代理对象

  1. 切面的优先级:在同一个JoinPoint上应用不同的Aspect,除非明确指定,否则它们的优先级是不确定的。

    指定切面优先级有两种方式:

    1. 在切面类标识@Order注解,并设置value参数为一个数字,数字越小,优先级越高
    2. 切面类实现Ordered接口,getOrder()方法的返回值越小,优先级越高
  2. 基于配置文件方式配置AOP

    <!–配置切面Bean–>
    <bean id=”logAspect” class=”com.andy.springtest.aop2.LogAspect”></bean>

    <!–配置AOP–>
    <aop:config>
    <!–声明切点–>
    <aop:pointcut id=”pointcut” expression=”execution(* com.andy.springtest.aop.UserService.*(..))”/>

    <!–配置切面–>
    <aop:aspect ref=”logAspect” order=”1″>
    <!–配置通知并指定切点–>
    <aop:before method=”beforeLogAdvice” pointcut-ref=”pointcut”/>
    <aop:after method=”afterLogAdvice” pointcut-ref=”pointcut”/>
    <aop:after-returning method=”afterReturnAdvice” pointcut-ref=”pointcut” returning=”isSuccess”/>
    <aop:after-throwing method=”afterThrowAdvice” pointcut-ref=”pointcut” throwing=”ex”/>
    <aop:around method=”aroundAdvice” pointcut-ref=”pointcut”/>
    </aop:aspect>

    </aop:config>

0 Comments
Leave a Reply