为什么 AOP 在我的 Spring Boot 项目中不起作用?它从不执行@Around 注释的方法
Why AOP is not working in my Spring Boot project? It never execute the @Around annoted method
我试图按照此视频教程将 AOP 添加到我的 Spring 引导项目以执行日志操作:https://www.youtube.com/watch?v=RVvKPP5HyaA
但是它不工作,它没有记录任何东西。
所以这是我的 pom.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.easydefi</groupId>
<artifactId>GET-USER-WS</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GET-USER-WS</name>
<description>Microservice that retrieves users from DB</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>nl.martijndwars</groupId>
<artifactId>web-push</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
如您所见,我向其添加了以下依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.3</version>
</dependency>
然后我创建了这个 LoggingAOP class 以配置 AOP 行为:
package com.easydefi.aop.logging;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.java.Log;
@Aspect
@Component
@Log
public class LoggingAOP {
@Pointcut(value = "execution(* com.easydefi.users.*.*.*(..))")
public void myPointcut() {
}
@Around("myPointcut()")
public Object applicationLogger(ProceedingJoinPoint pjp) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
Object[] argsArray = pjp.getArgs();
log.info("Method invoked " + className + ":" + methodName + "() arguments: " + mapper.writeValueAsString(argsArray));
Object response = pjp.proceed();
log.info(className + ":" + methodName + "() Response: " + mapper.writeValueAsString(response));
return response;
}
}
理论上使用的@Pointcut表达式:
@Pointcut(value = "execution(* com.easydefi.users.*.*.*(..))")
应该将所有方法的执行定义到项目根目录中定义的所有包的所有 class 中,即 com.easydefi.users 但它没有记录任何内容。
运行 我的应用程序并调用控制器方法或服务方法 我预计他会进入 applicationLogger() 方法。但它不起作用(我也在调试模式下尝试过,但它从未进入此方法)。
这是我的项目结构:
所以怎么了?我错过了什么?我该如何尝试修复它?
你的切入点
execution(* com.easydefi.users.*.*.*(..))
看起来有点不灵活,但它非常适合像
这样的拦截方法
public void com.easydefi.users.service.CoinService.doSomething()
public boolean com.easydefi.users.specification.MySpec.fooBar(int, String)
不适用于
public String com.easydefi.users.specification.criteria.MyCriteria.zot()
public void com.easydefi.users.aa.bb.cc.SomeService.zot()
原因 M。 Deinum 已经提到了。他建议使用 ..*
表示法,意思是“..*
前面的包中任何 class 中的任何方法”,完全正确:
execution(* com.easydefi.users..*(..))
我还想强调,这个答案的功劳应该是他的,如果他喜欢简单地复制我的答案并 post 用他自己的名字而不是评论,我会删除这个一个高兴地代替。但我确实认为问题应该得到全面的回答。
我试图按照此视频教程将 AOP 添加到我的 Spring 引导项目以执行日志操作:https://www.youtube.com/watch?v=RVvKPP5HyaA
但是它不工作,它没有记录任何东西。
所以这是我的 pom.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.easydefi</groupId>
<artifactId>GET-USER-WS</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GET-USER-WS</name>
<description>Microservice that retrieves users from DB</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>nl.martijndwars</groupId>
<artifactId>web-push</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
如您所见,我向其添加了以下依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.3</version>
</dependency>
然后我创建了这个 LoggingAOP class 以配置 AOP 行为:
package com.easydefi.aop.logging;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.java.Log;
@Aspect
@Component
@Log
public class LoggingAOP {
@Pointcut(value = "execution(* com.easydefi.users.*.*.*(..))")
public void myPointcut() {
}
@Around("myPointcut()")
public Object applicationLogger(ProceedingJoinPoint pjp) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
Object[] argsArray = pjp.getArgs();
log.info("Method invoked " + className + ":" + methodName + "() arguments: " + mapper.writeValueAsString(argsArray));
Object response = pjp.proceed();
log.info(className + ":" + methodName + "() Response: " + mapper.writeValueAsString(response));
return response;
}
}
理论上使用的@Pointcut表达式:
@Pointcut(value = "execution(* com.easydefi.users.*.*.*(..))")
应该将所有方法的执行定义到项目根目录中定义的所有包的所有 class 中,即 com.easydefi.users 但它没有记录任何内容。
运行 我的应用程序并调用控制器方法或服务方法 我预计他会进入 applicationLogger() 方法。但它不起作用(我也在调试模式下尝试过,但它从未进入此方法)。
这是我的项目结构:
所以怎么了?我错过了什么?我该如何尝试修复它?
你的切入点
execution(* com.easydefi.users.*.*.*(..))
看起来有点不灵活,但它非常适合像
这样的拦截方法public void com.easydefi.users.service.CoinService.doSomething()
public boolean com.easydefi.users.specification.MySpec.fooBar(int, String)
不适用于
public String com.easydefi.users.specification.criteria.MyCriteria.zot()
public void com.easydefi.users.aa.bb.cc.SomeService.zot()
原因 M。 Deinum 已经提到了。他建议使用 ..*
表示法,意思是“..*
前面的包中任何 class 中的任何方法”,完全正确:
execution(* com.easydefi.users..*(..))
我还想强调,这个答案的功劳应该是他的,如果他喜欢简单地复制我的答案并 post 用他自己的名字而不是评论,我会删除这个一个高兴地代替。但我确实认为问题应该得到全面的回答。