Haris Hasan
Haris Hasan

Reputation: 30097

How to write AspectJ AOP expression for this method?

I have tried many combinations but I am unable to invoke callback before execution of following method

@SomeAnnotation(...)
@Override
public void someMethod(Serializable id) {

}

I have tried many combinations similar to

@Before("execution(@com.full.name.of.SomeAnnotation  * com.full.name.of.Class.someMethod(java.io.Serializable))")
public void beforeMethod() {
    System.out.println("I am here.");
}

If I write a more generic expession, it hits the beforeMethod but I am unable to target a single specific method. What am I missing here?

Upvotes: 0

Views: 661

Answers (3)

kriegaex
kriegaex

Reputation: 67297

Okay guys, let me prove that the pointcut actually works as written by the original poster Haris Hasan.

Sample annotation:

package com.full.name.of;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface SomeAnnotation {
    int id();
    String name();
}

Sample class using the annotation:

package com.full.name.of;

import java.io.Serializable;

public class Class {
    @SomeAnnotation(id = 1, name = "John Doe")
    public void someMethod(Serializable s) {}

    public static void main(String[] args) {
        new Class().someMethod("x");
    }
}

Sample aspect with Haris Hasan's exact pointcut:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class SampleAspect {
    @Before("execution(@com.full.name.of.SomeAnnotation * com.full.name.of.Class.someMethod(java.io.Serializable))")
    public void yetAnotherPointcut(JoinPoint thisJoinPoint) {
        System.out.println(thisJoinPoint);
    }
}

Console output:

execution(void com.full.name.of.Class.someMethod(Serializable))

Copy and paste everything exactly as is, then run it. Quod erat demonstrandum.

Upvotes: 1

Marios
Marios

Reputation: 1957

Why do you not just use

@Before("execution(* com.full.name.of.Class.someMethod(java.io.Serializable))")

That specifically targets the method you want, you do not need to put the annotation to specify the target

Upvotes: 0

Atul
Atul

Reputation: 2711

The expression below should work:

@Before("com.full.name.of.Class.someMethod(..) && args(java.io.Serializable)")

Correction by kriegaex:

@Before("execution(* com.full.name.of.Class.someMethod(*)) && args(java.io.Serializable)")

A few points worth considering: Is the method being advised public? Are you using cglib proxies or jdk proxies? Does your class implement any interface and is the method being advised declared in the interface contract?

Also do take a look at what spring doc has to say about writing good pointcuts

Hope this helps.

Upvotes: 0

Related Questions