Spring的AOP详解

简介: Spring的AOP详解

8:AOP

8.1:入门案例

  • 导入相关依赖,AOP的依赖在Spring-context中已经被包含了,所以只需要再导入切面依赖即可
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.10.RELEASE</version>
</dependency>
<!--切面依赖-->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.4</version>
</dependency>
  • 自定义一个通知类(通知类必须配置成Spring管理的bean)
  • 设置通知类为切面类
  • 在Spring配置类中开启注解开发AOP功能
  • 设置要作为增强功能的方法和切入点
//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
    //设置切入点,要求配置在方法上方
    @Pointcut("execution(void com.ysj.dao.BookDao.update())")
    private void pt(){}
    //设置在切入点pt()的前面运行当前操作(前置通知)
    // @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

8.2:AOP工作流程

  1. Spring容器启动
  2. 读取页面所有的切入点
  3. 初始化bean,判断bean中是否有方法匹配到任意切入点
  • 匹配到,创建代理对象
  • 未匹配到,创建初始的对象
  1. 获取bean的执行方法
  • 获取bean,调用方法执行,完成操作
  • 获取的bean是代理对象时,执行是按照代理对象的运行方式运行原生方法和AOP定义的增强方法

Eg:在AOP中,AOP对最终的对象的ToString方法进行了重写,如果直接输出对象则是类似下面这样

`com.ysj.dao.impl.BookDaoImpl@4988d8b8`

8.3:AOP切入点表达式

  • *** ** :单个独立的任意符号,可独自出现,也可作为前缀或后缀的匹配符出现
  • :多个连续的任意符号,可独立出现,用于简化包名与参数的书写
  • + :专门用于匹配子类类型
//表示:任意返回值类型,在为顶层的包结构下任意包中的以Dao结尾的接口或类的子类中以up开头的无参方法
@Pointcut("execution(* com.*..*Dao+.up*())")

8.4:AOP通知类型

  • @before(“原始方法”):在原始方法运行之前
  • @after():在原始方法运行之后
  • @Around():环绕原始方法运行,可定义位置
  • 环绕通知必须依赖形参ProceedingJoinPoint才能在方法内部对原始方法进行调用
  • 未使用ProceedingJoinPoint将跳过原始方法的执行
  • 对原始方法接收返回值的话必须设置返回值类型为Object,不接收的话可void,也可Object
public Object around(ProceedingJoinPoint pjp)
  • 因为无法预知原始方法是否抛出异常,所以环绕通知必须抛出Throwable异常
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("around before advice ...");
    //表示对原始操作的调用
    Object ret = pjp.proceed();
    System.out.println("around after advice ...");
    return ret;  //返回原始方法执行的返回值
}
  • 另外俩(了解):
//@AfterReturning:返回后通知,在原始方法执行完毕后运行,且原始方法执行过程中未出现异常现象
//    @AfterReturning("pt2()")
    public void afterReturning() {
        System.out.println("afterReturning advice ...");
    }
    //@AfterThrowing:抛出异常后通知,在原始方法执行过程中出现异常后运行
    @AfterThrowing("pt2()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice ...");
    }

8.5:测试业务层接口执行效率

//设置环绕通知,在原始操作的运行前后记录执行时间
@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");
}

8.6:通知获取数据

  • ProceedingJonPoint:专用于环绕通知,是JoinPoint子类,可以实现对原始方法的调用
  • JoinPoint:用来描述切入点对象,但必须配置成通知方法中的第一个参数,可以实现对原始方法的调用
getArgs():用来获取原始方法中的参数,返回值是一个数组
  • 在原始方法return后和抛出异常后
//设置返回后通知获取原始方法的返回值,要求returning属性值必须与方法形参名相同
@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(JoinPoint jp,String ret) {
    System.out.println("afterReturning advice ..."+ret);
}
//设置抛出异常后通知获取原始方法运行时抛出的异常对象,要求throwing属性值必须与方法形参名相同
@AfterThrowing(value = "pt()",throwing = "t")
public void afterThrowing(Throwable t) {
    System.out.println("afterThrowing advice ..."+t);
}
相关文章
|
1月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
2月前
|
Java Spring
在Spring Boot中使用AOP实现日志切面
在Spring Boot中使用AOP实现日志切面
|
7天前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
1月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
20天前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
18 0
Spring高手之路22——AOP切面类的封装与解析
|
1月前
|
安全 Java 开发者
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
29 1
|
1月前
|
Java Spring
Spring的AOP组件详解
该文章主要介绍了Spring AOP(面向切面编程)组件的实现原理,包括Spring AOP的基础概念、动态代理模式、AOP组件的实现以及Spring选择JDK动态代理或CGLIB动态代理的依据。
Spring的AOP组件详解
|
1月前
|
Java API Spring
Spring Boot 中的 AOP 处理
对 Spring Boot 中的切面 AOP 做了详细的讲解,主要介绍了 Spring Boot 中 AOP 的引入,常用注解的使用,参数的使用,以及常用 api 的介绍。AOP 在实际项目中很有用,对切面方法执行前后都可以根据具体的业务,做相应的预处理或者增强处理,同时也可以用作异常捕获处理,可以根据具体业务场景,合理去使用 AOP。
|
20天前
|
Java Spring XML
掌握面向切面编程的秘密武器:Spring AOP 让你的代码优雅转身,横切关注点再也不是难题!
【8月更文挑战第31天】面向切面编程(AOP)通过切面封装横切关注点,如日志记录、事务管理等,使业务逻辑更清晰。Spring AOP提供强大工具,无需在业务代码中硬编码这些功能。本文将深入探讨Spring AOP的概念、工作原理及实际应用,展示如何通过基于注解的配置创建切面,优化代码结构并提高可维护性。通过示例说明如何定义切面类、通知方法及其应用时机,实现方法调用前后的日志记录,展示AOP在分离关注点和添加新功能方面的优势。
30 0
|
29天前
|
缓存 安全 Java
Spring AOP 中两种代理类型的限制
【8月更文挑战第22天】
14 0