Pekka
Pekka

Reputation: 171

@Aspect not called when using annotation

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?

Upvotes: 1

Views: 1935

Answers (1)

Eulodos
Eulodos

Reputation: 634

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.

Upvotes: 1

Related Questions