0

I am new to Spring and AOP. I am trying this simple thing where I have created a custom annotation which when placed before any method should execute some code. This is the annotation I created

    // Declares a custom annotation that validates json
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface JsonSchemaAnnotation {
    }

Next I created the Spring Aspect class which holds the logic

@Aspect
public class UpdateUIMetadataInterceptor {

@Pointcut("execution(public * com.fico.cardinal.cm.*.*(..))")
public void anyPublicMethod() {
    System.out.println("Running");
}

@Before("anyPublicMethod() && @annotation(jsonSchemaAnnotation)")
public void validateJson(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("Running");  
}

}

And this is my simple test class

public class ValidationTest {

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring/configuration.xml");
    String jsondata = "{\"id\": \"EXPENSE_REPORT\",\"properties\": {\"transactionType\": \"EXPENSE_REPORT\"},\"sections\": []} ]}";
    ValidationTest test = new ValidationTest();
    test.jsonValidationTest("dummy", jsondata);
    ((AbstractApplicationContext) context).close();


}

@JsonSchemaAnnotation
public void jsonValidationTest(String dummy, String jsondata) {
    System.out.println("Success");

}

The problem is my spring aop never gets triggered. I have included a bean in my configuration.xml

<aop:aspectj-autoproxy>
    <aop:include name="UpdateUIMetadataInterceptor" />
</aop:aspectj-autoproxy>
<bean id="updateUI"      class="com.fico.cardinal.cm.interceptor.UpdateUIMetadataInterceptor" />

Can anyone point out what I am missing?

3
  • I have followed this blog
    – rrrocky
    Commented Aug 13, 2015 at 11:00
  • 1
    You create your ValidationTest object using new, so it's not managed by Spring. You have to have it as a bean in your application context and then obtain reference to it through your context variable Commented Aug 13, 2015 at 11:04
  • Created it via bean just now. Still no improvement. I think I am missing something more.
    – rrrocky
    Commented Aug 13, 2015 at 11:07

2 Answers 2

2

You have several problems with your code:

  1. You should create your ValidationTest object as a bean managed by Spring and not using new
  2. <aop:include name="UpdateUIMetadataInterceptor" /> should be <aop:include name="updateUI"/>; you can actually just stick with <aop:aspectj-autoproxy/> for simplicity here
  3. ProceedingJoinPoint is not supported for before aspects, so remove it; you can use JoinPoint instead if you need access to arguments
  4. JsonSchemaAnnotation jsonSchemaAnnotation parameter should be present for validateJson method of your aspect, as pointed out by frant.hartm
10
  • Yep this should do it, I have missed the wrong include name :-) Commented Aug 13, 2015 at 11:40
  • I need to use the parameters of the annotated methods. That's why I have used ProceedingJoinPoint. How am I supposed to get access to the parameters without using that?
    – rrrocky
    Commented Aug 13, 2015 at 12:32
  • I have edited my code according to your suggestions. (Check question) But still my aspect class is not triggered.
    – rrrocky
    Commented Aug 13, 2015 at 12:36
  • You can use JoinPoint instead of ProceedingJoinPoint. Can you please update all of the code in your question? I tried to run an app configured just like yours and advice is triggered. Also include contents of your pom.xml Commented Aug 13, 2015 at 13:36
  • Check out my edited code. I have also included the pom.xml
    – rrrocky
    Commented Aug 13, 2015 at 13:51
1

I think you need either fully qualified name or a parameter in the method:

FQN:

@Before("anyPublicMethod() && @annotation(your.package.JsonSchemaAnnotation)")
public void validateJson(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("Running");  
}

Parameter:

@Before("anyPublicMethod() && @annotation(jsonSchemaAnnotation)")
public void validateJson(ProceedingJoinPoint pjp, JsonSchemaAnnotation jsonSchemaAnnotation ) throws Throwable {
    System.out.println("Running");  
}

Source: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-pointcuts

(and you also need to use the bean, as Dmitry Kuskov pointed out

1
  • I tried both fully qualified name @Before("anyPublicMethod() && @annotation(com.fico.cardinal.cm.interceptor.JsonSchemaAnnotation)") and parameter public void before(ProceedingJoinPoint pjp, JsonSchemaAnnotation jsonSchemaAnnotation) throws Throwable But it does not work in either case
    – rrrocky
    Commented Aug 13, 2015 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.