企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# Spring AOP 围绕建议示例 > 原文: [https://howtodoinjava.com/spring-aop/aspectj-around-advice-example/](https://howtodoinjava.com/spring-aop/aspectj-around-advice-example/) 在这个 Spring aop 示例中,我们将学习使用`<aop:around/>`配置来使用 **AOP** 围绕建议。 配置为围绕建议的方法,在与作为参数传递的切入点表达式匹配的方法之前运行。 在此阶段,您必须确定是否应调用原始方法,因为从此处您可以终止应用程序流并直接返回值,而无需调用原始建议方法。 在此示例中,我们将创建简单的 spring 应用程序,添加日志记录切面,然后基于在`<aop:around/>` xml 配置中传递的切入点信息来调用切面方法。 ## 创建 Spring AOP 围绕建议 要使用 xml 配置创建**围绕建议**,请按以下方式使用`<aop:around/>`。 ```java <aop:config> <aop:aspect ref="loggingAspect"> <aop:pointcut expression="execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))" id="loggingPointcuts"/> <!-- around advice --> <aop:around method="logAroundAllMethods" pointcut-ref="loggingPointcuts" /> </aop:aspect> </aop:config> ``` 建议方法将具有类型为`ProceedingJoinPoint`的方法参数,可用于调用建议方法。 ```java public void logAroundAllMethods(ProceedingJoinPoint pjp) throws Throwable { System.out.println("****LoggingAspect.logAroundAllMethods() - Before method call"); pjp.proceed(); System.out.println("****LoggingAspect.logAroundAllMethods() - After method call"); } ``` ## 项目结构 ![Spring AOP Project Structure](https://img.kancloud.cn/e5/86/e586f19859a2c6a8c2b0abf70ea319bc_398x468.jpg) Spring AOP 项目结构 ## Spring AOP AspectJ Maven 依赖关系 我添加了 spring 核心,spring aop 和 Aspectj 依赖项。 ```java <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd; <modelVersion>4.0.0</modelVersion> <groupId>com.howtodoinjava</groupId> <artifactId>SpringAOPExamples</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Spring AOP Examples</name> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> </dependencies> </project> ``` ## 添加 Spring AOP 配置 在 XML 配置文件中,您可以添加`aop:config`元素以添加 AOP 支持。 ```java <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:config> <aop:aspect ref="loggingAspect"> <aop:pointcut expression="execution(* com.howtodoinjava.app.service.impl.EmployeeManagerImpl.*(..))" id="loggingPointcuts"/> <aop:around method="logAroundAllMethods" pointcut-ref="loggingPointcuts" /> </aop:aspect> </aop:config> <!-- Employee manager --> <bean id="employeeManager" class="com.howtodoinjava.app.service.impl.EmployeeManagerImpl" /> <!-- Logging Aspect --> <bean id="loggingAspect" class="com.howtodoinjava.app.aspect.LoggingAspect" /> </beans> ``` ## 需要执行切面的服务方法 `EmployeeManager.java`和`EmployeeManagerImpl.java` ```java public interface EmployeeManager { public EmployeeDTO getEmployeeById(Integer employeeId); public List<EmployeeDTO> getAllEmployee(); public void createEmployee(EmployeeDTO employee); public void deleteEmployee(Integer employeeId); public void updateEmployee(EmployeeDTO employee); } public class EmployeeManagerImpl implements EmployeeManager { public EmployeeDTO getEmployeeById(Integer employeeId) { System.out.println("Method getEmployeeById() called"); return new EmployeeDTO(); } public List<EmployeeDTO> getAllEmployee() { System.out.println("Method getAllEmployee() called"); return new ArrayList<EmployeeDTO>(); } public void createEmployee(EmployeeDTO employee) { System.out.println("Method createEmployee() called"); } public void deleteEmployee(Integer employeeId) { System.out.println("Method deleteEmployee() called"); } public void updateEmployee(EmployeeDTO employee) { System.out.println("Method updateEmployee() called"); } } ``` ## 编写切面类和方法 编写切面类和要作为建议执行的方法。 ```java package com.howtodoinjava.app.aspect; import org.aspectj.lang.ProceedingJoinPoint; public class LoggingAspect { public void logAroundAllMethods(ProceedingJoinPoint pjp) throws Throwable { System.out.println("****LoggingAspect.logAroundAllMethods() - Before method call"); pjp.proceed(); System.out.println("****LoggingAspect.logAroundAllMethods() - After method call"); } } ``` ## 测试 Spring AspectJ 的配置和执行 现在,我们来测试以上配置的切面是否在给定的切入点信息上执行。 ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.howtodoinjava.app.model.EmployeeDTO; import com.howtodoinjava.app.service.EmployeeManager; public class TestMain { @SuppressWarnings("resource") public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); EmployeeManager manager = (EmployeeManager) context.getBean("employeeManager"); manager.getEmployeeById(1); manager.createEmployee(new EmployeeDTO()); } } ``` ```java ****LoggingAspect.logAroundAllMethods() - Before method call Method getEmployeeById() called ****LoggingAspect.logAroundAllMethods() - After method call ****LoggingAspect.logAroundAllMethods() - Before method call Method createEmployee() called ****LoggingAspect.logAroundAllMethods() - After method call ``` 显然,在相关联点上执行的切面为**围绕建议**。 学习愉快! 参考文献: [Spring AOP 参考](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html) [AspectJ 项目](https://eclipse.org/aspectj/) [不同的切入点表达式以及示例](https://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with-examples/)