springAOP落地实现

文章目录


前言

江湖阳哥曾经说过这么句话:

使用技术在当前这个环境中无非就是这么几步:

1、引入POM(maven)坐标

2、改yml(配置文件也可以是properties等等)

3、写配置类或者在启动类上加注解

4、写代码就完事


提示:以下是本篇文章正文内容,下面案例可供参考

一、熟悉相关概念:

在Spring AOP中,注解是

定义切面(Aspects)、切点(Pointcuts)、通知(Advice)等的主要方式。

以下是Spring AOP中几种常见的注解及其用途和如何使用:

1、@Aspect:

  • 作用:标识一个类为切面类。
  • 使用方式:将此注解标注在类上,这个类会包含切点和通知的定义。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    // 切点和通知定义...
}

2、@Pointcut:

  • 作用:定义一个切点,即横切关注点的入口,明确什么样的方法调用会被拦截。
  • 使用方式:在方法声明前使用此注解,并提供一个切点表达式,该方法本身通常是空方法,仅作为切点的引用。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethod() {}
    // 其他通知...
}

3、@Before:

  • 作用:定义一个前置通知,在切点的方法执行之前执行。
  • 使用方式:将此注解放在一个方法上,该方法将在目标方法执行前执行。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @Before("serviceMethod()")
    public void beforeServiceMethod() {
        // 前置逻辑...
    }
}

4、@AfterReturning:

  • 作用:定义一个返回后通知,如果切点的方法正常返回后执行。
  • 使用方式:将此注解放在一个方法上,并通过该方法提供的参数记入返回的值。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @AfterReturning(pointcut = "serviceMethod()", returning = "retVal")
    public void afterReturning(Object retVal) {
        // 处理返回值...
    }
}

5、@AfterThrowing:

  • 作用:定义一个异常通知,如果切点的方法抛出异常后执行。
  • 使用方式:将此注解放在一个方法上,并可选地获取抛出的异常。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @AfterThrowing(pointcut = "serviceMethod()", throwing = "ex")
    public void afterThrowing(Exception ex) {
        // 异常处理...
    }
}

6、@After:

  • 作用:定义一个最终通知,无论切点的方法是正常返回还是抛出异常都会执行。
  • 使用方式:将此注解放在一个方法上,该方法无论目标方法如何都会执行。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @After("serviceMethod()")
    public void afterServiceMethod() {
        // 最终逻辑...
    }
}

7、@Around:

  • 作用:定义一个环绕通知,可以自定义在目标方法前后执行的逻辑,同时决定是否继续执行目标方法。
  • 使用方式:将此注解放在一个方法上,该方法需要返回一个Object,可能是目标方法的返回值,也可能是你自定义的返回值。你可以在此方法中直接调用目标方法。
  • 示例:
java 复制代码
@Aspect
public class MyAspect {
    @Around("serviceMethod()")
    public Object aroundServiceMethod(ProceedingJoinPoint pjp) throws Throwable {
        // 前置逻辑...
        Object result = pjp.proceed(); // 执行目标方法
        // 后置逻辑...
        return result;
    }
}

Spring AOP的使用通常有两种方式:

通过注解驱动的方式:在配置类上使用 @EnableAspectJAutoProxy 注解开启AOP支持,然后声明切面类和相关注解。

通过XML配置的方式:在XML文件中定义 aop:config 元素,并在该元素内部配置切面和通知。

通常情况下,注解驱动的方式更简洁直观,且是推荐的做法。不过,在某些用例或旧项目中,XML配置方式可能还是会用到。

二、具体使用case:

当然,让我们以一个简单的AOP用例为例,实现一个记录方法执行时间的切面。首先确保您的项目已经加入了Spring AOP的相关依赖,例如,使用Maven时,您可以添加下列依赖到您的pom.xml文件:

1.pom文件

java 复制代码
<!-- Spring AOP 依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.18</version>
</dependency>
<!-- AOP联盟API -->
<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
</dependency>
<!-- Spring框架的一部分,用于处理AOP的代理 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.18</version>
</dependency>

2.代码

现在,让我们创建一个切面,该切面会记录方法执行的时间:

java 复制代码
// 具有@Aspect注解的类会被Spring识别为一个切面
@Aspect
// 确保这个类被Spring的容器扫描到,通常它应该位于@ComponentScan指定的包或子包中
@Component
public class PerformanceAspect {

    // 切点表达式,这里是指任意返回值的Service层中的任意方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethod() {}

    // 环绕通知,让我们可以在方法执行前后添加自定义逻辑
    @Around("serviceMethod()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis(); // 开始时间
        Object output = pjp.proceed(); // 执行被代理的方法
        long elapsedTime = System.currentTimeMillis() - start; // 计算消耗的时间
        System.out.println("Method execution time: " + elapsedTime + " milliseconds.");
        return output; // 返回被代理方法的返回值
    }
}

然后,你需要在Spring的配置类加入如下内容,以启用AOP的自动代理功能:

java 复制代码
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example") // 修改为你的包名
public class AppConfig {
    // 可以添加额外的Bean配置...
}

现在,你的AOP切面已经准备好了。当你的程序运行时,任何匹配Pointcut(位于com.example.service包的任意方法)的方法都会被PerformanceAspect所拦截,它会在方法执行前后记录执行时间,并将该时间打印到控制台。

假设我们有一个简单的服务类:

java 复制代码
package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class SimpleService {

    public void doSomething() {
        // 模拟业务逻辑处理时间
        try {
            Thread.sleep(1000); 
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

当你调用SimpleService类的doSomething方法时,上述的PerformanceAspect会自动拦截此调用,并且记录该方法的执行时间。这样你就完成了一个针对Spring的AOP入门级案例。


总结

好了尽情的开发使用吧,其实这个是为了我写那个面试题的文章准备的哈哈哈哈

相关推荐
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
冰糖码奇朵5 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好5 小时前
【Spring】整合【SpringMVC】
java·spring
浪九天6 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
小斌的Debug日记6 小时前
框架基本知识总结 Day16
redis·spring
堕落年代6 小时前
Maven匹配机制和仓库库设置
java·maven
m0_748246876 小时前
maven导入spring框架
数据库·spring·maven
功德+n6 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
香精煎鱼香翅捞饭7 小时前
java通用自研接口限流组件
java·开发语言
ChinaRainbowSea7 小时前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构