详解SpringBoot之集成Spring AOP

下面是详解SpringBoot之集成SpringAOP的完整攻略:

什么是Spring AOP

Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要模块。它实现了基于代理的AOP,并且与IOC容器无缝集成,提供了便捷的配置方式。

面向切面编程就是将通用的横切关注点(如日志、安全、事务等)从业务逻辑中分离出来,形成一个独立的逻辑单元,这样可以在不干扰业务逻辑的情况下,清晰、模块化地实现这些横切关注点。

Spring AOP的核心概念

Spring AOP的核心概念包括:

  • 切面(Aspect):它是横切关注点的模块化。切面定义了在哪个连接点(JoinPoint)上执行哪个通知(Advice)。

  • 连接点(Join Point):程序的执行时机,如方法执行或异常抛出等。

  • 切入点(Pointcut):匹配连接点的规则,用于限定通知执行的范围。

  • 通知(Advice):执行在连接点上的操作。通知包括忽略返回值、在连接点前后执行的增强处理、环绕通知等。

  • 引入(Introduction):在通知之外为类型添加新的方法或属性,一般不太用到。

  • 织入(Weaving):把切面应用到目标对象并创建新的代理对象的过程。

Spring AOP的通知类型包括:

  • 前置通知(Before Advice):在连接点之前运行的通知方法。

  • 后置通知(After Advice):在连接点之后运行的通知方法。

  • 返回通知(After Returning Advice):在连接点正常完成后运行的通知方法。

  • 异常抛出通知(After Throwing Advice):在连接点抛出异常后运行的通知方法。

  • 环绕通知(Around Advice):在连接点前后都运行的通知方法。

Spring AOP的使用

现在我们来看看在Spring Boot中如何集成Spring AOP。下面是步骤:

步骤一:引入AOP依赖

在maven配置文件中,添加以下依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

步骤二:创建切面类

在创建切面时,需要使用@Aspect注解标注,同时定义切点和通知类型。以下是一个简单的切面类的示例代码:

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(public * com.example.demo.service..*.*(..))")
    public void logPointcut(){}

    @Before("logPointcut()")
    public void beforeMethod(JoinPoint jp){
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 调用开始。");
    }

    @AfterReturning(returning = "result", pointcut = "logPointcut()")
    public void afterReturningMethod(JoinPoint jp, Object result) {
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 调用结束。返回值:" + result);
    }

    @AfterThrowing(throwing = "ex", pointcut = "logPointcut()")
    public void afterThrowingMethod(JoinPoint jp, Exception ex) {
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 抛出异常:" + ex.getMessage());
    }
}

以上代码定义了一个切面类:LogAspect,其中定义了三个通知。

  • 前置通知:在连接点之前输出方法调用开始的提示语句。

  • 返回通知:在连接点正常完成后输出方法调用结束和返回值的提示语句。

  • 异常抛出通知:在连接点抛出异常后输出异常提示语句。

步骤三:在应用程序中使用切面

在需要应用切面的类或方法上使用@Aspect注解即可,下面是一个简单的示例:

@Service
public class DemoService {

    public String sayHello(String name) {
        System.out.println("Hello, " + name);
        return "result";
    }

    @Log
    public void doSomething(String input){
        System.out.println("doing something...");
    }
}

在上述示例中,我们在方法doSomething上使用了@Log注解,该注解作为一个切点进行切入。

示例

下面是一个完整的示例代码:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            DemoService demoService = ctx.getBean(DemoService.class);
            String greeting = demoService.sayHello("World");
            System.out.println(greeting);
            demoService.doSomething("test");
        };
    }
}

@Service
public class DemoService {

    public String sayHello(String name) {
        System.out.println("Hello, " + name);
        return "result";
    }

    @Log
    public void doSomething(String input){
        System.out.println("doing something...");
    }
}

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.example.demo.annotation.Log)")
    public void logPointcut(){}

    @Before("logPointcut()")
    public void beforeMethod(JoinPoint jp){
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 调用开始。");
    }

    @AfterReturning(returning = "result", pointcut = "logPointcut()")
    public void afterReturningMethod(JoinPoint jp, Object result) {
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 调用结束。返回值:" + result);
    }

    @AfterThrowing(throwing = "ex", pointcut = "logPointcut()")
    public void afterThrowingMethod(JoinPoint jp, Exception ex) {
        String className = jp.getSignature().getDeclaringTypeName();
        String methodName = jp.getSignature().getName();
        System.out.println("==> " + className + "." + methodName + "() 抛出异常:" + ex.getMessage());
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {}

在上述示例代码中:

  • DemoService类中定义了一个sayHello方法和一个doSomething方法,并在doSomething方法上使用了@Log注解。

  • LogAspect切面类中定义了一个切点和三个通知。

  • @Log注解是我们自定义的注解,在需要记录日志的方法上进行标注。

当我们运行上述代码时,可以看到控制台输出了以下内容:

Hello, World
==> com.example.demo.service.DemoService.doSomething() 调用开始。
doing something...
==> com.example.demo.service.DemoService.doSomething() 调用结束。返回值:null

以上就是集成Spring AOP的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解SpringBoot之集成Spring AOP - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • java实现异步导出数据

    为了让读者更加易懂,本文将采用三个部分讲解异步导出数据。 1. 后端实现异步导出 对于导出数据这种后端耗时较长的操作,我们一般采用异步导出的方式来解决。下面是后端实现异步导出的主要步骤: 1.1 前端发起导出请求,后端生成导出任务 前端发起导出请求时,后端会先生成一个唯一的任务id,将任务id返回给前端,并把导出任务存储到数据库中。 1.2 后端异步执行导出…

    Java 2023年5月26日
    00
  • Spring学习JdbcTemplate数据库事务参数

    下面就是关于“Spring学习JdbcTemplate数据库事务参数”的完整攻略: 1. JdbcTemplate概述 JdbcTemplate是Spring框架中一个非常重要的核心组件,它为开发者提供了非常方便的方式进行数据访问操作。它提供了完善的JDBC功能支持,并简化了JDBC代码的编写。JdbcTemplate底层实现了对JDBC进行封装和简化,更加…

    Java 2023年5月20日
    00
  • java通过JFrame做一个登录系统的界面完整代码示例

    下面我将为你详细讲解如何使用Java通过JFrame做一个登录系统的界面。 前提准备 在开始编写代码之前,我们需要先确保已经安装好了Java开发环境,推荐使用Eclipse开发工具。 第一步:搭建界面 在Java中,JFrame是我们常用的界面设计类。我们首先需要实例化一个JFrame类,并为其设置一些基本的属性,比如窗口大小、标题等。示例如下: impor…

    Java 2023年5月24日
    00
  • java BigDecimal精度丢失及常见问分析

    下面是对于“java BigDecimal精度丢失及常见问题分析”的完整攻略。 1. 背景 在Java中进行精确浮点数计算,常常使用BigDecimal类。BigDecimal类有很强的精度和舍入模式控制能力,但是如果不注意使用规范,也会出现与浮点数相似的精度问题:丢失精度。 2. 问题分析 2.1 浮点数精度问题 Java中的浮点数精度问题主要由二进制浮点…

    Java 2023年5月27日
    00
  • Mybatis分页插件PageHelper配置及使用方法详解

    下面我就为您详细讲解”Mybatis分页插件PageHelper配置及使用方法详解”。 一、PageHelper简介 PageHelper是一款Mybatis分页插件,它提供了分页的基本功能,包括支持MySQL、Oracle、SQLServer等数据库,支持多种分页查询方式,同时也提供了更好的Spring集成方式。 二、PageHelper使用方法 1.导入…

    Java 2023年5月20日
    00
  • SpringBoot日期格式转换之配置全局日期格式转换器的实例详解

    SpringBoot日期格式转换之配置全局日期格式转换器的实例详解 在SpringBoot开发中,日期格式转换是一项非常重要的工作。如果不进行日期格式转换,会导致很多问题,比如接收到的时间格式不正确,数据库存储的时间也不正确等等。为了解决这些问题,我们可以通过配置全局日期格式转换器来实现。下面我们将详细讲解如何配置。 配置全局日期格式转换器的方式 第一种方式…

    Java 2023年6月1日
    00
  • 在jsp页面如何获得url参数

    在JSP页面中,我们可以通过request对象获取URL参数。下面是获取URL参数的完整攻略: 在JSP页面中使用request对象获取URL参数 我们可以通过request.getParameter()方法来获取请求中的特定参数。 示例1: 获取单个参数值 假设我们有一个URL http://www.example.com/index.jsp?name=J…

    Java 2023年6月15日
    00
  • 一文讲解如何优雅的调试jar包

    一文讲解如何优雅地调试jar包 在开发过程中,我们经常会用到jar包来提供或使用某些功能,而在使用过程中,有时需要调试jar包中的代码,以定位或解决问题。本文将介绍如何优雅地调试jar包,以提高我们的开发效率。 1. 使用源码依赖 当我们使用某些jar包时,如果其提供了源码,我们可以将其作为项目的依赖包,这样就可以在IDE中直接调试jar包源码了。 具体步骤…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部