Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3.2 AOP - Intercepting methods by annotation

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?

like image 891
Lancelot Avatar asked Feb 05 '13 18:02

Lancelot


People also ask

What is the difference between JoinPoint and pointcut?

JoinPoint: Joinpoint are points in your program execution where flow of execution got changed like Exception catching, Calling other method. PointCut: PointCut are basically those Joinpoints where you can put your advice(or call aspect). So basically PointCuts are the subset of JoinPoints.

What is the use of @aspect annotation in Spring?

Spring AspectJ AOP implementation has many annotations. They are explained below: @Aspect: It declares the class as an aspect. @Pointcut: It declares the pointcut expression.

What is @aspect annotation in spring boot?

@AspectJ refers to a style of declaring aspects as regular Java classes annotated with Java 5 annotations. The @AspectJ style was introduced by the AspectJ project as part of the AspectJ 5 release.

What is AspectJ used for?

AspectJ implements both concerns and the weaving of crosscutting concerns using extensions of Java programming language.


1 Answers

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?

like image 62
nicholas.hauschild Avatar answered Nov 03 '22 01:11

nicholas.hauschild