📜  返回建议后的Spring Boot AOP(1)

📅  最后修改于: 2023-12-03 15:12:19.726000             🧑  作者: Mango

返回建议后的Spring Boot AOP

Spring Boot AOP(面向切面编程)是一个强大的工具,可以优化代码并提高应用程序性能。在本文中,我们将讨论如何返回建议后的Spring Boot AOP,以及如何将它应用于实际应用程序工作中。

什么是Spring Boot AOP?

Spring Boot AOP是一个 Java 编程库,它允许开发人员将代码切成小片段,这样就可以在多个模块中重复使用这些片段。它在运行时创建一个代理,将对象包装在其中,以便在方法调用时添加切面。这样就可以节省代码并提高应用程序性能。

如何实现建议后

要使用Spring Boot AOP实现建议后,需要执行以下步骤:

  1. 定义建议类
  2. 定义切入点
  3. 应用切入点和建议

现在,我们将逐一讨论这些步骤。

步骤1:定义建议类

建议类用于定义建议的类型,分为以下五种:

  1. 前置建议:这种建议在方法调用之前运行。
  2. 后置建议:这种建议在方法返回后运行。
  3. 后终止建议:这种建议在方法正常退出之后运行。
  4. 抛出建议:这种建议在抛出异常后运行。
  5. 环绕建议:这种建议围绕方法调用运行。

下面是一个示例:

@Component
@Aspect
public class LoggingAspect {
 
    @Before("execution(public void com.example..*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }

    @After("execution(public void com.example..*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("logAfter() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }

    @AfterReturning(
      pointcut = "execution(public * com.example.service.StudentService.getStudentById(..))",
      returning= "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("logAfterReturning() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("Method returned value is : " + result);
        System.out.println("******");
    }

    @AfterThrowing(
      pointcut = "execution(public * com.example.service.StudentService.getStudentById(..))",
      throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("logAfterThrowing() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("Exception : " + error);
        System.out.println("******");
    }
 
}
步骤2:定义切入点

切入点是要执行建议的地方。例如,在以下代码中:

@Component
public class StudentService {
 
    public Student getStudentById(Integer id) {
        System.out.println("Executing getStudentById()");
        return new Student(id, "John Doe");
    }
 
}

切入点就是getStudentById()函数。

步骤3:应用切入点和建议

现在我们已经定义了建议类和切入点,下一步是将它们应用到代码中。

在Spring Boot应用程序中,应该在应用程序类上加上 @EnableAspectJAutoProxy 注释,例如以下代码:

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

这将使Spring Boot AOP从 Spring 应用程序上下文中自动检测建议,并将其应用于切入点。

实践

现在我们已经讨论了如何实现建议后的Spring Boot AOP,让我们看一个示例。

假设我们有一个 StudentService 类,它具有以下方法:

@Component
public class StudentService {
 
    public Student getStudentById(Integer id) {
        System.out.println("Getting student information for student with id: " + id);
        return new Student(id, "John Doe");
    }
 
    public void addStudent(Student student) {
        System.out.println("Adding student to the student list: " + student);
    }
 
}

要实现建议后,您可以创建以下切入点和建议:

@Aspect
@Component
public class LoggingAspect {
 
    @Before("execution(public * com.example.service.StudentService.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before - " + joinPoint.getSignature().getName());
    }

    @After("execution(public * com.example.service.StudentService.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("After - " + joinPoint.getSignature().getName());
    }

    @AfterReturning(
      pointcut = "execution(* com.example.service.StudentService.*(..))",
      returning= "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("After Returning - " + joinPoint.getSignature().getName());
    }

    @AfterThrowing(
      pointcut = "execution(* com.example.service.StudentService.*(..))",
      throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("After Throwing - " + joinPoint.getSignature().getName());
    }
 
}

在前面的代码中,我们使用了多个建议类型:前置建议、后置建议、后返回建议和抛出建议。

现在,我们已经创建了这些建议,我们可以在 StudentController 类中使用它们:

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(method=RequestMethod.GET, value="/students/{id}")
    public Student getStudentById(@PathVariable Integer id) {
        return studentService.getStudentById(id);
    }

    @RequestMapping(method=RequestMethod.POST, value="/students")
    public void addStudent(@RequestBody Student student) {
        studentService.addStudent(student);
    }

}

这将自动将建议应用于在StudentController中定义的方法。

现在,我们已经成功地实施了Spring Boot AOP后的建议。这将使我们可以创建更可重用和可维护的代码,并提高应用程序的性能。