Spring 3.2 AOP - Intercepting methods by annotation

12,413

In your test code, you are not allowing Spring to create your MyComponent, but instead, you are using the new operator. You should be accessing MyComponent from Spring's ApplicationContext.

public class SomeTest {
    public static void main(String[] args) throws Exception {
        final ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
        final MyComponent myComponent = appContext.getBean(MyComponent.class);
        //your test here...
    }
}

If you do not get your component from Spring, how do you expect it to be proxied?

Share:
12,413
Lancelot
Author by

Lancelot

Software Engineer with experience in Node.js, C#, Java

Updated on June 05, 2022

Comments

  • Lancelot
    Lancelot almost 2 years

    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:

    1. @Around("@annotation(com.myapp.annotation.MyAnnotation)") public Object process(ProceedingJoinPoint jointPoint) throws Throwable { .. }

    2. @Around(value="@annotation(myAnnotation)", argNames="myAnnotation") public Object process(ProceedingJoinPoint jointPoint, MyAnnotation myAnnotation) throws Throwable { .. }

    3. @Around("execution(* com.myapp.*.*(..)) && @annotation(com.myapp.annotation.MyAnnotation)") public Object process(ProceedingJoinPoint jointPoint) throws Throwable { .. }

    What am I doing wrong?