SpringAop

作用 

    在不修改原来代码的前提下,实现对代码的增强功能;

          比如:使用 aop 实现日志:https://www.cnblogs.com/Jomini/p/13218872.html

 

使用:https://www.cnblogs.com/liantdev/p/10125284.html

  Join point 连接点

    连接点是程序执行的一个点.。一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。举例来说,所有定义在你的 EmpoyeeManager接口中的方法都可以被认为是一个连接点

  Pointcut 切点

    一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。举例来说,所有定义在你的 EmpoyeeManager接口中的方法都可以被认为是一个连接点

//匹配com.aop.service.impl.ProductServiceImpl类下方法名以select或delete开头的所有方法
@Pointcut("execution(* com.aop.service.impl.ProductServiceImpl.select*(..)) || " +
            "execution(* com.aop.service.impl.ProductServiceImpl.delete*(..))")
public void matchCondition() {}

//使用matchCondition这个切入点进行增强
@Before("matchCondition()")
public void before() {
   System.out.println("before 前置通知......");
   authService.checkAccess();
}

 

  Advice

    通知是指拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知、后置通知、异常通知、最终通知和环绕通知(切面要完成的功能)

    1.@Before前置通知
      前置通知在切入点运行前执行,不会影响切入点的逻辑
    2.@After后置通知
      后置通知在切入点正常运行结束后执行,如果切入点抛出异常,则在抛出异常前执行
    3.@AfterThrowing异常通知
      异常通知在切入点抛出异常前执行,如果切入点正常运行(未抛出异常),则不执行
    4.@AfterReturning返回通知
      返回通知在切入点正常运行结束后执行,如果切入点抛出异常,则不执行
    5.@Around环绕通知
      环绕通知是功能最强大的通知,可以在切入点执行前后自定义一些操作。环绕通知需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行

//匹配com.aop.service.impl.ProductServiceImpl类下面的所有方法
    @Pointcut("execution(* com.aop.service.impl.ProductServiceImpl.*(..))")
    public void matchAll() {}

    @Around("matchAll()")
    public Object around(ProceedingJoinPoint joinPoint) {
        Object result = null;
        authService.checkAccess();
        System.out.println("befor 在切入点执行前运行");

        try{
            result = joinPoint.proceed(joinPoint.getArgs());//获取参数
            System.out.println("after 在切入点执行后运行,result = " + result);
        } catch (Throwable e) {
            System.out.println("after 在切入点执行后抛出exception运行");
            e.printStackTrace();
        } finally {
            System.out.println("finally......");
        }

       return result;
    }

 

  Aspect

    Aspect切面表示Pointcut(切入点)和Advice(增强/通知)的结合

 

Spring Aop中四个重要概念,切点,切面,连接点,通知 关系

  1. 通知: 就是我们编写的希望Aop时执行的那个方法。我们通过Aop希望我们编写的方法在目标方法执行前执行,或者执行后执行。
  2. 切点:切点就是我们配置的满足我们条件的目标方法。比如我们规定:名字前面是select开头的才执行我们自定义的通知方法。那么这些select开头的方法就是切点。
  3. 连接点:连接点可以说是切点的全集。切点是连接点的子集。也可以理解为,连接点是我们没有定义那个select开头规则时,满足条件的全部的方法。
  4. 切面:切面是切点和通知的组合称谓,就是变相给组合起了个名字。

 

实现原理

          使用 Cglib动态代理 实现

          Cglib 对比 动态代理

            Cglib 底层使用 ASM 框架,来操作字节码生成新的类

     动态代理 只能对接口代理,没有接口就不能实现

     动态代理提供 Proxy 类来创建代理,Cglib 提供 Enhancer 来创建代理

       参考:https://www.cnblogs.com/Jomini/p/13272571.html

 

使用方式

  官方文档:https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#aop-enable-aspectj-xml

 

aspect 切面

  Point cut (如果理解了这个切点的概念,就在应用方面完全是可以的了)表示连接点的集合(类似一个表)

  Join point 目标对象中的方法(每一条记录)

  weaving 把代理逻辑加入到目标对象上的过程叫做织入

  advice 通知类型,请下下图官网说明

 

 

面试:

问:  

  是编译时期进行织入,还是运行期进行织入?

答:

  运行期,生成字节码,再加载到虚拟机中,JDK是利用反射原理,CGLIB使用了ASM原理。

 

问:

  初始化时期织入还是获取对象时织入?

答:

  初始化的时候,已经将目标对象进行代理,放入到spring 容器中

 

源码分析:

posted @ 2020-08-21 15:15  李荣先辈Java  阅读(134)  评论(0编辑  收藏  举报