• AOP(Aspect-Oriented Programming)即面向切面编程,它与OOP相辅相成,提供了与OOP不同的抽象软件结构的视角。
    • OOP以类作为程序的基本单元,AOP的基本单元是Aspect(切面)
    1. 切面:切面(Aspect)是指封装横切到系统功能(如事务处理)的类。
    2. 连接点:连接点(Joinpoint)是指程序运行中的一些时间点,如方法的调用或异常的抛出。
    3. 切入点:切入点(Pointcut)是指那些需要处理的连接点。在Spring AOP 中,所有的方法执行都是连接点,而切入点是一个描述信息,它修饰的是连接点,通过切入点确定哪些连接点需要被处理。
    4. 通知(增强处理,advice):由切面添加到特定的连接点(满足切入点规则)的一段代码,即在定义好的切入点处所要执行的程序代码。可以将其理解为切面开启后,切面的方法。因此,通知是切面的具体实现。
    5. 引入:引入(Introduction)允许在现有的实现类中添加自定义的方法和属性。
    6. 目标对象:目标对象(Target Object)是指所有被通知的对象。如果AOP 框架使用运行时代理的方式(动态的AOP)来实现切面,那么通知对象总是一个代理对象。
    7. 代理:代理(Proxy)是通知应用到目标对象之后,被动态创建的对象。
    8. 织入:织入(Weaving)是将切面代码插入到目标对象上,从而生成代理对象的过程。根据不同的实现技术,AOP织入有三种方式:编译期织入,需要有特殊的Java编译器;类装载期织入,需要有特殊的类装载器;动态代理织入,在运行期为目标类添加通知生成子类的方式。Spring AOP框架默认采用动态代理织入,而AspectJ(基于Java语言的AOP框架)采用编译期织入和类装载期织入。

    •Java有多种动态代理技术,例如JDK、CGLIB、Javassist、ASM等。
    •目前,Spring AOP中常用JDK和CGLIB两种动态代理技术。

    •JDK动态代理是java.lang.reflect.包提供的方式,它必须借助一个接口才能产生代理对象。
    •对于使用业务接口的类,Spring默认使用JDK动态代理实现AOP。
    基于代理类的AOP实现
    *——
    1. 通知类型
    •根据Spring中通知在目标类方法的连接点位置,可以分为6种如下类型:

    1. 环绕通知(org.aopalliance.intercept.MethodInterceptor)
      是在目标方法执行前和执行后实施增强,可以应用于日志记录、事务处理等功能。
    2. 前置通知(org.springframework.aop.MethodBeforeAdvice)
      是在目标方法执行前实施增强,可应用于权限管理等功能。
    3. 后置返回通知(org.springframework.aop.AfterReturningAdvice)
      是在目标方法成功执行后实施增强,可应用于关闭流、删除临时文件等功能。
    4. 后置(最终)通知(org.springframework.aop.AfterAdvice)
      是在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该通知,可应用于释放资源。
    5. 异常通知(org.springframework.aop.ThrowsAdvice)
      是在方法抛出异常后实施增强,可以应用于处理异常、记录日志等功能。
    6. 引入通知(org.springframework.aop.IntroductionInterceptor)
      是在目标类中添加一些新的方法和属性,可以应用于修改目标类(增强类)。

    7. ProxyFactoryBean
      •ProxyFactoryBean是org.springframework.beans.factory.FactoryBean接口的实现类,FactoryBean负责实例化一个Bean实例,ProxyFactoryBean负责为其他Bean实例创建代理实例。

    •ProxyFactoryBean类的常用属性

    属性 描述
    target 代理的目标对象
    proxyInterfaces 代理需要实现的接口列表,如果是多个接口,可以使用以下格式赋值:



    interceptorName 需要织入目标的Advice
    proxyTargetClass 是否对类代理而不是接口,默认为false,使用JDK动态代理;当为true时,使用CGLIB动态代理
    singleton 返回的代理是否为单例,默认为true
    optimize 当设置为true时强制使用CGLIB动态代理

    基于XML配置开AspectJ
    •AspectJ是一个基于Java语言的AOP框架。从Spring 2.0以后引入了AspectJ的支持。目前的Spring框架,建议开发者使用AspectJ实现Spring AOP。使用AspectJ实现Spring AOP的方式有两种:
    –基于XML配置开发AspectJ
    –基于注解开发AspectJ。

    •基于XML配置开发AspectJ是指通过XML配置文件定义切面、切入点及通知,所有这些定义都必须在元素内。

    元素名称 用途
    开发Aspect的顶层配置元素,在配置文件的下可以包含多个该元素
    配置(定义)一个切面,元素的子元素,属性ref指定切面的定义
    配置切入点,元素的子元素,属性expression指定通知增强哪些方法
    配置前置通知,元素的子元素,属性method指定前置通知方法,属性pointcut-ref指定关联的切入点
    配置后置返回通知,元素的子元素,属性method指定后置返回通知方法,属性pointcut-ref指定关联的切入点
    配置环绕通知,元素的子元素,属性method指定环绕通知方法,属性pointcut-ref指定关联的切入点
    配置异常通知,元素的子元素,属性method指定异常通知方法,属性pointcut-ref指定关联的切入点,没有异常发生时将不会执行
    配置后置(最终)通知,元素的子元素,属性method指定后置(最终)通知方法,属性pointcut-ref指定关联的切入点
    给通知引入新的额外接口,增强功能

    基于注解开发AspectJ
    •基于注解开发AspectJ要比基于XML配置开发AspectJ便捷许多。

    注解名称 描 述
    @Aspect 用于定义一个切面,注解在切面类上
    @Pointcut 用于定义切入点表达式。在使用时,需要定义一个切入点方法。该方法是一个返回值void,且方法体为空的普通方法
    @Before 用于定义前置通知。在使用时,通常为其指定value属性值,该值可以是已有的切入点,也可以直接定义切入点表达式
    @AfterReturning 用于定义后置返回通知。在使用时,通常为其指定value属性值,该值可以是已有的切入点,也可以直接定义切入点表达式
    @Around 用于定义环绕通知。在使用时,通常为其指定value属性值,该值可以是已有的切入点,也可以直接定义切入点表达式
    @AfterThrowing 用于定义异常通知。在使用时,通常为其指定value属性值,该值可以是已有的切入点,也可以直接定义切入点表达式。另外,还有一个throwing属性用于访问目标方法抛出的异常,该属性值与异常通知方法中同名的形参一致
    @After 用于定义后置(最终)通知。在使用时,通常为其指定value属性值,该值可以是已有的切入点,也可以直接定义切入点表达式