Spring AOP

AOP简介:

  • 面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
  • *作用:在不惊动原始设计的基础上为其进行功能增强。

AOP核心概念

  • (1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
  • (2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
  • 在SpringAOP中,理解为方法的执行。
  • (3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
  • 在SpringAOP中,功能最终以方法的形式呈现。
  • (4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
  • 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法。
    • 一个具体方法: com.it.dao包下的BookDao接口中的无形参无返回值的save方法。
    • 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法
  • (5)通知类:定义通知的类。
  • (6)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类。

AOP工作流程

2.读取所有切面配置中的切入点。

3.初始化bean,判定bean对应的类中的方法是否匹配到任意切入点

  • 匹配失败,创建对象
  • 匹配成功,创建原始对象(目标对象)的代理对象

4.获取bean只想方法

  • 获取bean,调用方法并执行,完成操作
  • 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

AOP切入点表达式

1.execution:指示符,execution是最常用的指示符,用于匹配方法执行的连接点。

2.public:访问修饰符,该参数可选。

3.第一个 _号:返回值类型,_号表示所有的类型,即通配符。

4.包名:需要拦截的包名,后面的两个点表示当前包和当前包的所有子包,即例子中的com. ljb.service.impl包和该包的子孙包下所有类。

5.第二个 _号:类名,_号表示所有的类。

  1. _(..):方法名,_号表示所有方法,括号里面表示方法的参数,两个点表示任何参数,可有可无。

AOP通知类型

//前置通知:在方法执行前通知
@Before(value = “”)

//环绕通知:可以将要执行的方法(point.proceed())进行包裹执行,可以在前后添加需要执行的操作 (重点)
@Around(value = “”)

//后置通知:在方法正常执行完成进行通知,可以访问到方法的返回值的。
@After(value = “”)

//异常通知:在方法出现异常时进行通知,可以访问到异常对象,且可以指定在出现特定异常时在执行通知。
@AfterThrowing(value = “”)

//方法执行后通知: 在目标方法执行后无论是否发生异常,执行通知,不能访问目标方法的执行的结果。
@AfterReturning(value = “”)

1. 环绕通知必须依赖形参ProceedingJoinPoint才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知

2. 通知中如果未使用ProceedingJoinPoint对原始方法进行调用将跳过原始方法的执行

3. 对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,必须设定为Object类型

4. 原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void,也可以设置成Object

5. 由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throable对象

代码:


@Component
@Aspect
public class ProjectAdvice {

    @Pointcut("execution(* com.it.service.*Service.*(..))")
    private void servicePt(){}

    //设置环绕通知,在原始操作的运行前后记录执行时间
    @Around("ProjectAdvice.servicePt()")
    public void runSpeed(ProceedingJoinPoint pjp) throws Throwable {
        //获取执行的签名对象
        Signature signature = pjp.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            pjp.proceed();
        }
        long end = System.currentTimeMillis();
        System.out.println("万次执行:"+ className+"."+methodName+"---->" +(end-start) + "ms");
    }
}

Original: https://www.cnblogs.com/zhangyouren/p/16578410.html
Author: Haziy
Title: Spring AOP

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574409/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Skywalking-10:Skywalking查询协议——GraphQL

    GraphQL GraphQL 基础 参照Getting started with GraphQL Java and Spring Boot这篇文章学习即可 PS:可以使用 bre…

    Java 2023年6月5日
    087
  • java基础4.20

    1.是否可以从一个static方法内部发出对非static方法的调用?不可以。因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而st…

    Java 2023年6月5日
    050
  • 【转】消息中间件MQ的学习境界和路线

    原文:https://www.cnblogs.com/xiexj/p/16095395.html Original: https://www.cnblogs.com/tc310/p…

    Java 2023年5月29日
    095
  • java内存区域模型和详解

    一,概述 java虚拟机运行时数据区模型图: 主要包括:程序计数器,java虚拟机栈,本地方法栈,java 堆,方法区(元空间)。 其中堆和方法区由所有线程共享的数据区;程序计数器…

    Java 2023年6月13日
    062
  • 从头开始 启动开源电商项目jShop

    1. 引言 干了三年C#, 有了转Java 的念想,所以尝试学习一下java web,java语法本身和C#没有太多的差别,所以打算看看开源的java项目,开源的Java项目还是非…

    Java 2023年6月5日
    074
  • CSharp: Template Method Pattern

    csharp;gutter:true; /// /// Summary description for Triangle.</p> <pre><cod…

    Java 2023年6月16日
    067
  • Java中的static关键字

    在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个”伪全局”的概念,在Java中static表示”全局”或者…

    Java 2023年5月29日
    0112
  • 使用Gradle构建Java项目

    使用Gradle构建Java项目 这个手册将通过一个简单的Java项目向大家介绍如何使用Gradle构建Java项目。 我们将要做什么? 我们将在这篇文档中创建一个简单的Java项…

    Java 2023年5月29日
    0130
  • 在Ubuntu机器上使用war包安装Jenkins

    因为一些需求需要迁移之前使用的Jenkins,原来是按照官方文档使用apt方式安装的,这次搬迁后的机器由于默认不通外网(可以通过代理走外网),因此趁此机会,尝试改用war包方式安装…

    Java 2023年6月14日
    083
  • Hexo博客部署到腾讯云服务器全过程(Nginx,证书,HTTPS),你要的这里都有

    背景 说来也惭愧,博客已经搭建很久了,一直免费的部署在 Coding 和 Github Pages 上,前者迁移到腾讯云 Serverless,导致原有的配置始终有问题,没时间仔细…

    Java 2023年6月7日
    081
  • LeetCode.1103-向人们分发糖果(Distribute Candies to People)

    这是小川的第 393次更新,第 425篇原创 今天介绍的是 LeetCode算法题中 Easy级别的第 256题(顺位题号是 1103)。我们通过以下方式向一排 n = num_p…

    Java 2023年6月5日
    073
  • 20220930-Vector集合扩容机制源码分析

    总结: ArrayList与Vector集合的底层都是通过Object[] elementData数组存放对象的 ArrayList使用无参构造器时,初始容量为0,当存放一个对象后…

    Java 2023年6月15日
    089
  • MacOS设置终端代理

    前言 国内的开发者或多或少都会因为网络而烦恼,因为一些特殊原因有时候网络不好的时候需要使用代理才能完成对应的操作。原来我一直都是使用斐讯路由器然后刷了梅林的固件,直接在路由器层面设…

    Java 2023年6月5日
    0121
  • MyBatis 使用(XML版本)

    一、MyBatis相关概念 对象 / 关系数据库映射(ORM) ORM全称Object/Relation Mapping:表示对象-关系映射的缩写 ORM完成⾯向对象的编程语⾔到关…

    Java 2023年6月5日
    083
  • Seata源码分析——RPC模块底层实现

    前言 总览 AbstractNettyRemotingClient——一个RPC请求方法 RpcMessage——RPC协议 编码&解码 Server端Netty初始化 S…

    Java 2023年6月9日
    0112
  • out与err输出流

    System.in、System.out与System.err 当我们查阅文档可知,out与err都是Java中的输出流,in是”标准”输入流,System…

    Java 2023年6月5日
    078
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球