为什么 AOP 在我的 Spring 引导应用程序中不起作用?
Why AOP does not work in my Spring Boot application?
我试图将 AspectJ 添加到我的 Spring 引导项目之一,但失败了。我试图创建非常简单的 Spring 引导项目,但它也不起作用。我已经添加了 @EnableAspectJAutoProxy 注释等,但仍然相同。我做错了什么?
这是这个简单项目的代码:
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Aspect
@Component
public class MessageAspect {
@Before("execution(* com.example.demo.MessageController.mainMethod())")
public void beforeMethod() {
System.out.println("before method");
}
}
@RestController
public class MessageController {
@RequestMapping(value = "/")
public String mainMethod() {
return "result from mainMethod";
}
}
Maven 依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
这些是我认为对你有帮助的:
- 你忘了添加你的 aspect 的 bean class:
@Bean MessageAspect messageAspect() {
return new MessageAspect();
}
使用 @EnableAspectJAutoProxy
不使用 (proxyTargetClass = true)
确保您的 @Aspect
注释被扫描。你可以使用 @ComponentScan("myAspectPackageContainer.*")
您不再需要使用 @Aspect
时的 @Component
注释。
- 在你的表达式中使用方法修饰符
"execution( public * com.example.demo..."
- 在表达式末尾使用
"myPackage.*.*(..)"
- 检查这两个依赖项:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
顺便说一句,如果你只需要看一下你的控制器,你可以使用 @ControllerAdvice
classes
删除 @Component
注释在这种情况下帮助了我。
你在接受的答案中的评论救了我,所以我认为最好将它添加为其他人的答案:
我使用了 IntelliJ 的“Create Aspect”创建了一个扩展名为 .aj
的文件。我不明白为什么其他 classes 看不到我的新方面 class,即使 IntelliJ 正在自动完成它。 IntelliJ 隐藏了文件扩展名,并且图标与 class 相同,因此并不明显。
在 IntelliJ 项目管理器中将文件重命名为 .java
解决了我的问题。
我试图将 AspectJ 添加到我的 Spring 引导项目之一,但失败了。我试图创建非常简单的 Spring 引导项目,但它也不起作用。我已经添加了 @EnableAspectJAutoProxy 注释等,但仍然相同。我做错了什么?
这是这个简单项目的代码:
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Aspect
@Component
public class MessageAspect {
@Before("execution(* com.example.demo.MessageController.mainMethod())")
public void beforeMethod() {
System.out.println("before method");
}
}
@RestController
public class MessageController {
@RequestMapping(value = "/")
public String mainMethod() {
return "result from mainMethod";
}
}
Maven 依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
这些是我认为对你有帮助的:
- 你忘了添加你的 aspect 的 bean class:
@Bean MessageAspect messageAspect() { return new MessageAspect(); }
使用
@EnableAspectJAutoProxy
不使用(proxyTargetClass = true)
确保您的
@Aspect
注释被扫描。你可以使用@ComponentScan("myAspectPackageContainer.*")
您不再需要使用
@Aspect
时的@Component
注释。- 在你的表达式中使用方法修饰符
"execution( public * com.example.demo..."
- 在表达式末尾使用
"myPackage.*.*(..)"
- 检查这两个依赖项:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency>
顺便说一句,如果你只需要看一下你的控制器,你可以使用 @ControllerAdvice
classes
删除 @Component
注释在这种情况下帮助了我。
你在接受的答案中的评论救了我,所以我认为最好将它添加为其他人的答案:
我使用了 IntelliJ 的“Create Aspect”创建了一个扩展名为 .aj
的文件。我不明白为什么其他 classes 看不到我的新方面 class,即使 IntelliJ 正在自动完成它。 IntelliJ 隐藏了文件扩展名,并且图标与 class 相同,因此并不明显。
在 IntelliJ 项目管理器中将文件重命名为 .java
解决了我的问题。