I’m trying to intercept any method tagged w/ a custom annotation and the reason you read this is because I can’t get it to work. I’ve been following simple examples but can’t get it to work.
Here is my code.
MyAnnotation.java:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default "";
String key() default "";
String condition() default "";
}
MyAspect.java:
@Aspect
public class MyAspect {
@Pointcut(value="execution(public * *(..))")
public void anyPublicMethod() { }
@Around("anyPublicMethod() && @annotation(myAnnotation)")
public Object process(ProceedingJoinPoint jointPoint, MyAnnotation myAnnotation) throws Throwable {
System.out.println("In AOP process");
return 5; //jointPoint.proceed();
}
}
spring-config.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd">
...
<context:component-scan base-package="com.myapp">
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="myAspect" class="com.myapp.annotation.MyAspect" />
...
MyComponent.java:
@Component
public class MyComponent {
@MyAnnotation(value="valtest", key="keytest", condition="contest")
public int add(int i, int j) {
System.out.println("Executing annotation.add");
return i+j;
}
}
Test code:
final MyComponent m = new MyComponent();
assertTrue(5 == m.add(0, 1)); // Here m.add(...) always returns 1 instead of 5.
As a side note I’ve tried to define my pointcut many different ways, all with and without the use of the anyPublic() method and its execution pointcut, but none of those worked for me:
-
@Around("@annotation(com.myapp.annotation.MyAnnotation)")
public Object process(ProceedingJoinPoint jointPoint) throws Throwable { .. } -
@Around(value="@annotation(myAnnotation)", argNames="myAnnotation")
public Object process(ProceedingJoinPoint jointPoint, MyAnnotation myAnnotation) throws Throwable { .. } -
@Around("execution(* com.myapp.*.*(..)) && @annotation(com.myapp.annotation.MyAnnotation)")
public Object process(ProceedingJoinPoint jointPoint) throws Throwable { .. }
What am I doing wrong?
In your test code, you are not allowing Spring to create your
MyComponent, but instead, you are using thenewoperator. You should be accessingMyComponentfrom Spring’sApplicationContext.If you do not get your component from Spring, how do you expect it to be proxied?