zoukankan      html  css  js  c++  java
  • AOP技术及其Spring中的应用

    一、AOP是什么

    AOP(Aspect Oriented Programming)是面向切面编程,是一种设计思想,它要在不改变原有目标对象的基础上,为目标对象基于动态织入的特定方式(可以是编译是的动态,也可以运行时的动态)进行功能扩展.我们可以将设计思想理解为OOP(面向对象编程)思想的补充和完善,OOP强调的一种静态过程(一个项目由哪些子系统构成,一个子系统有哪些模块,一个模块又由哪些对象构成,一个对象又有哪些属性和方法).AOP是一个动态过程,它要为设计好的对象在动态编译或运行时做服务增益,例如,记录日志,事务增强,权限控制等。
     
    其实就是要在不修改源代码的基础上对对象功能进行功能拓展。

    二、AOP应用原理初步分析

    有两种方式

    1、借助JDK官方API为目标对象类型创建其兄弟类型对象,但是目标对象类型需要实现相应接口

    2、借助CGLIB库为目标对象类型创建其子类类型对象,但是目标对象类型不能使用final修饰.

    三、AOP相关术语

    1、切面对象(Aspect)

    封装了扩展业务逻辑的对象,在spring中可以使用@AspectJ描述

    2、切入点(Pointcut)

    定义了切入扩展业务逻辑的一些方法的集合(哪些方法运行时切入扩展业务),一般会通过表达式进行相关定义,一个切面中可以定义多个切入点的定义

    3、连接点(JoinPoint)

    切入点方法集合中封装了某个正在执行的目标方法信息的对象,可以通过此对象获取具体的目标方法信息,甚至去调用目标方法

    4、通知(Advice)

    切面(Aspect)内部封装扩展业务逻辑的具体方法对象,一个切面中可以有多个通知(例如@Around)

     

    可以简单的将机场的一个安检口理解为连接点,多个安检口为切入点,安全检查过程看成是通知

    四、Spring中关于Aop的注释

    1、@Aspect

    该注解描述的类型为切面对象类型,此切面中可以定义多个切入点和通知方法

    2、@Pointcut

    该注解用于定义切入点

    3、@Around

    该注解描述的方法,可以在切入点执行之前和之后进行业务拓展,在当前业务中

    五、Spring切面对象定义

    在springboot工程中,切面对象需要@Aspect

     1 package XXX;
     2 
     3 @Slf4j
     4 @Aspect
     5 @Component
     6 public class SysLogAspect {
     7     /**
     8      * bean("spring容器中bean的名字")这个表达式为切入点表达式定义的一种语法,
     9      * 它描述的是某个bean或多个bean中所有方法的集合为切入点,这个形式的切入点
    10      * 表达式的缺陷是不能精确到具体方法的.
    11      */
    12      @Pointcut("bean(sysUserServiceImpl)")
    13      public void doLog(){}//此方法只负责承载切入点的定义
    14 
    15     /**
    16      * 此方法为日志通知方法
    17      * @param joinPoint 连接点对象,此对象封装了要执行的切入点方法信息.可以通过连接点对象调用目标方法,这里的ProceedingJoinPoint类型只能应用于@Around描述的方法参数中
    18      * @return 目标方法的执行结果
    19      * @throws Throwable
    20      */
    21      @Around("doLog()")
    22      public Object doAround(ProceedingJoinPoint jp)throws Throwable{
    23          log.info("Start:{}",System.currentTimeMillis());
    24          try {
    25              Object result = jp.proceed();//执行目标方法(切点方法中的某个方法)
    26              log.info("After:{}",System.currentTimeMillis());
    27              return result;//目标业务方法的执行结果
    28          }catch(Throwable e){
    29              e.printStackTrace();
    30              log.error("Exception:{}",System.currentTimeMillis());
    31              throw e;
    32          }
    33      }
    34 }
    View Code

    六、Spring切面工作原理分析

    切面内部,切入点对应的目标业务方法执行时,底层会通过代理对象访问切面中的通知方法,进而通过通知方法为目标业务做功能增强.

    JDK动态代理对象应用分析:

     其中:springboot工程默认的AOP代理为CGLIB代理,假如希望是JDK代理,则需要在springboot的配置文件中进行如下配置:

    spring: 
       aop: 
         proxy-target-class: false

    CGLIB动态代理对象应用分析:

    七、Aop通知类型

    Spring框架AOP模块定义通知类型,有如下几种:

    1、@Around (所有通知中优先级最高的通知,可以在目标方法执行之前,之后灵活进行业务拓展.)

    2、@Before (目标方法执行之前调用)

    3、@AfterReturning (目标方法正常结束时执行)

    4、@AfterThrowing (目标方法异常结束时执行)

    5、@After (目标方法结束时执行,正常结束和异常结束它都会执行)

    八、Aop切入点表达式

    在Spring工程中对于切入点表达式,可以分成两大类型:

    • 粗粒度切入点表达式定义(不能精确到具体方法),例如bean,within表达式

    • 细粒度切入点表达式定义(可以精确到具体方法),例如execution,@annotation表达式

    粗粒切入点表达式

    1、bean(“bean的名字”) 表达式案例分析

    1 1) bean(XxxServiceImpl),XxxServiceImpl类中所有方法集合为切入点
    2 2) bean(*ServiceImpl),以ServiceImpl结尾的所有方法集合为切入点

    2、within ("包名.类型") 表达式案例分析

    1 1) within(XxxServiceImpl),XxxServiceImpl类中所有方法集合为切入点
    2 2) within(Xxx.*),Xxx.service包下所有类中的方法集合为切入点
    3 3) within(Xxx.service..*),Xxx.service包以及子包中所有类中方法的集合为切入点

    细粒度切入点表达式

    3、execution("返回值 类全名.方法名(参数列表)") 表达式案例分析

    1 1) execution(int XxxService.validById(Integer,Integer))
    2 2) execution(* Xxx.service..*.*(..))

    4、@annotation(“注解的类全名”)表达式案例分析

    1 1) @annotation(Xxx),由RequiredCache注解描述的方法为缓存切入点方法
    2 2) @annotation(Xxx),由RequiredLog注解描述的方法为日志切入点方法

    九、Aop切面优先级设置

    当有多个切面时,并且对应着相同的切入点,假如切面中的通知方法的执行需要有严格顺序要求,此时我们需要设置切面的优先级。这个优先级可以通过@Order(数字优先级)注解进行描述,数字越小优先级越高。

    设置日志切面优先级:

    1 @Order(2)
    2 @Aspect
    3 @Component
    4 public class XXX{}

    设置缓存切面优先级:

    1 @Order(1)
    2 @Aspect
    3 @Component
    4 public class XXX{}

    假如默认没有指定优先级,默认是最低的优先级。相同切入点下的多个切面会形成一个切面链。

  • 相关阅读:
    SpringCloud-Hystrix Dashboard 之 Unable to connect to Command Metric Stream
    try() catch{}
    git使用和操作
    外部服务器使用jedis操作redis数据库
    Tomcat部署spring boot项目
    java成神之路截图
    innodb 死锁分析之相关表结构说明
    mysql 死锁案例及分析过程
    Head First设计模式之观察者(Observer)模式(二)
    Head First设计模式之策略模式(Strategy)
  • 原文地址:https://www.cnblogs.com/houyu/p/14278858.html
Copyright © 2011-2022 走看看