英文:
@Aspect not called when using annotation
问题
我创建了一个注解,用于执行以下操作:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface Verify {
}
还有一个切面:
@Aspect
@Component
public class VerifyAspect {
@Before("execution(public * *(.., @Verify (*), ..))")
public void actionBefore(JoinPoint joinPoint) {
System.out.println(joinPoint); // <<-------------- 看不到这条消息
}
}
以及一个配置:
@Configuration
@EnableAspectJAutoProxy
public class VerifyConfig {
}
但是当我调用:
public void method(@Verify MyObject obj){
// 做点什么
}
切面根本没有被调用。我在创建过程中有什么错误吗?
英文:
I create an annotation to make some operations as bellow:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface Verify {
}
and an Aspect:
@Aspect
@Component
public class VerifyAspect {
@Before("execution(public * *(.., @Verify (*), ..))")
public void actionBefore(JoinPoint joinPoint) {
System.out.println(joinPoint); // <<-------------- can't see this message
}
}
and a config:
@Configuration
@EnableAspectJAutoProxy
public class VerifyConfig {
}
But when I call:
public void method(@Verify MyObject obj){
// do something
}
The Aspect not called at all. do I make any mistake in my creation?
答案1
得分: 1
从 [spring docs](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html?fbclid=IwAR0FN-ulrxzncCYNwz6JCJob1OCOLJ_uqNGFmjp-oP4JV1KWBrn_20D7XiY#aop-introduction-spring-defn) 中得知:Spring AOP 目前仅支持方法执行连接点(在 Spring bean 上通知方法的执行)- 因此请确保您正在调用的方法
public void method(@Verify MyObject obj){
// do something
}
被声明在一个 Spring Bean 内。
根据您分享的代码,我创建了一个简单的演示:
同时确保 aspectjweaver.jar 在您的依赖项中
**pom.xml**
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
**主应用程序类**
@SpringBootApplication
public class AspecjStyleAopApplication {
public static void main(String[] args) {
SpringApplication.run(AspecjStyleAopApplication.class, args);
}
}
**配置类**
在这里,确保为 Spring 提供正确的 basePackages 以扫描您的组件
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.example")
public class AspectJConfig {
}
**注解**
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface Verify {
}
**切面类**
@Aspect
@Component
public class VerifyAspect {
@Before("execution(public * *(.., @Verify (*), ..))")
public void actionBefore(JoinPoint joinPoint) {
System.out.println("应显示此内容");
System.out.println(joinPoint); // <<-------------- 看不到此消息
}
}
**Service 类**
@Service
public class SampleService {
public void method(@Verify Object obj){
System.out.println("传递的对象:" + obj);
}
}
**RestController 类**
@RestController
public class SampleRestController {
private final SampleService sampleService;
public SampleRestController(SampleService sampleService) {
this.sampleService = sampleService;
}
@GetMapping("/sample")
public String sampleRestMethod() {
sampleService.method(5);
return "操作成功";
}
}
当我调用 `http://localhost:8080/sample` 端点时,控制台输出如下:
应显示此内容
execution(void com.example.aspecjstyleaop.SampleService.method(Object))
传递的对象:5
第二行是您希望看到的输出。
英文:
From the spring docs : Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans) - So make sure, the method you are calling
public void method(@Verify MyObject obj){
// do something
}
is declared inside one of the Spring Beans.
Based on the code you've shared, I created a simple demo:
Also make sure, the aspectjweaver.jar is in your dependencies
pom.xml
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
Main Application
@SpringBootApplication
public class AspecjStyleAopApplication {
public static void main(String[] args) {
SpringApplication.run(AspecjStyleAopApplication.class, args);
}
}
Configuration
Here, make sure you provide the correct basePackages for Spring to scan for your components
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.example")
public class AspectJConfig {
}
Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface Verify {
}
Aspect
@Aspect
@Component
public class VerifyAspect {
@Before("execution(public * *(.., @Verify (*), ..))")
public void actionBefore(JoinPoint joinPoint) {
System.out.println("THIS SHOULD BE DISPLAYED");
System.out.println(joinPoint); // <<-------------- can't see this message
}
}
Service
@Service
public class SampleService {
public void method(@Verify Object obj){
System.out.println("Passed object: " + obj);
}
}
RestController
@RestController
public class SampleRestController {
private final SampleService sampleService;
public SampleRestController(SampleService sampleService) {
this.sampleService = sampleService;
}
@GetMapping("/sample")
public String sampleRestMethod() {
sampleService.method(5);
return "It works";
}
}
And the output from the console, when I call http://localhost:8080/sample
endpoint:
THIS SHOULD BE DISPLAYED
execution(void com.example.aspecjstyleaop.SampleService.method(Object))
Passed object: 5
Second line is what you wanted to see printed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论