0

The project structure is

  1. spring-contract
  2. spring-aop as dependency of (1)
  3. spring-service as dependency of (2).

I have a param annotation @MyAnnotation in spring-contract project, an aspect class in spring-aop,

package com.learning.aspect;

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

@Aspect
public class AnnotatedFieldAspect {

    @Before("execution(* *(.., @MyAnnotation (*), ..)) && args(newValue)")
    public void advice(JoinPoint jp, Object newValue) {
        System.out.println(">>> inspecting "+newValue+" on "+jp.getTarget()+", "+jp.getSignature());
    }
}

The class which will be advised by the annotation is in spring-service project,

package com.learning.fieldtest.service;

public class TestField {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(@MyAnnotation String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        TestField testField = new TestField();
        testField.setName("Alex");
        testField.m1(testField.getName());
        System.out.println(testField.getName());
    }

    public void m1(@MyAnnotation String string) {
        System.out.println("Inside m1() @MyAnnotation" + string);
    }
}

The class TestField methods are not marked as advised, if i move all the classes in the same package i get result. There are other aspects which is written at class and method level that is getting applied.

>>> inspecting Alex on com.learning.fieldtest.service.TestField@3fa77460, void com.learning.fieldtest.service.TestField.setName(String)
>>> inspecting Alex on com.learning.fieldtest.service.TestField@3fa77460, void com.learning.fieldtest.service.TestField.m1(String)
Inside m1() @MyAnnotationAlex
Alex

Custom Annotation

package com.learning.spring.contract;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface MyAnnotation {
}
tinker_fairy
  • 1,323
  • 1
  • 15
  • 18
  • Not an answer, just an observation -This is a pure Aspectj code as no spring related annotations are there. – R.G Feb 09 '20 at 00:30
  • You didn't show your annotation class and specifically not its package name - please learn what an [MCVE](https://stackoverflow.com/help/mcve) is and why it is so valuable - but unless the annotation happens to be in the exact same package as the aspect, you need to use its fully qualified class name in the pointcut, such as `execution(* *(.., @com.learning.whatever.MyAnnotation (*), ..))`. – kriegaex Feb 09 '20 at 02:29
  • @kriegaex have added the code, i tried it – tinker_fairy Feb 09 '20 at 02:49
  • As I guessed already, your annotation is in a different package than the aspect. So your pointcut should start with `execution(* *(.., @com.learning.spring.contract.MyAnnotation (*), ..))`. You said you tried but didn't report the result. Not very helpful. So does it work like I suggested? Then I can convert my comments into an answer which you can then accept + upvote in order to close the question. – kriegaex Feb 09 '20 at 04:12
  • The aspect is not applied, there is warning in the aspect "advice defined in com.learning.spring.contract.AnnotatedFieldAspect has not been applied [Xlint:adviceDidNotMatch]". I tried this option to only check for `@Before("execution(* com.com.learning.fieldtest.service..*(..))") and @Before("within(com.com.learning.fieldtest.service.*)")` same warning message – tinker_fairy Feb 09 '20 at 13:49
  • I inspected the .class files with decompiler, the class is advised but eclipse is not showing. The aspect plugin is there, the hierarchy is not shown under crossover. – tinker_fairy Feb 10 '20 at 13:01

1 Answers1

0

In one of your spring config class add @EnableAspectJAutoProxy. This will enable the aspect processing in spring app.

    @Configuration
    @EnableAspectJAutoProxy
     public class AppConfig {

         @Bean
         public FooService fooService() {
             return new FooService();
         }

         @Bean
         public MyAspect myAspect() {
             return new MyAspect();
         }
     }

For more details refer: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/EnableAspectJAutoProxy.html

Satish
  • 1,037
  • 1
  • 13
  • 20
  • The OP already reported that the aspect works if all classes are in the same package. So obviously he already configured Spring AOP correctly and his problem is a different one. – kriegaex Feb 09 '20 at 04:14
  • actually, the aspect config is in spring-contract project and he is trying to apply that for a class in spring-service project, so it will not work unless in spring-service also aspect is enabled via. @EnableAspectJAutoProxy. (even though its applied in spring-contract). He mentioned that when he copies the file to same package which i think he copies from spring-contract project to spring-service project, it worked. So, i believe he just need to enable the aspect again in all the projects where-ever he wanna use the aspect. – Satish Feb 09 '20 at 04:52
  • You might be right but I would be very surprised. I never used Spring before, so I cannot be sure, but my understanding is that Spring configuration applies globally and not per Maven module. How would the application know which class comes from which module and then intentionally treat it differently? This makes no logical sense to me. – kriegaex Feb 09 '20 at 07:43
  • You are also right. Spring does honour configuration class from dependent modules, but it’s not applicable to few specific annotations, e.g “@Aspect” unless it’s enabled in every child project. I’m quoting an explanation from official doc “Note: “@EnableAspectJAutoProxy“ applies to its local application context only, allowing for selective proxying of beans at different levels. Please redeclare “@EnableAspectJAutoProxy” in each individual context”. Refer: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/EnableAspectJAutoProxy.html – Satish Feb 09 '20 at 16:42