Yan Tuizhi opened SPR-15809 and commented

I have made the following test application with spring boot 1.5.3:

@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(TestApplication.class);
        context.getBean(ClassA.class).init();
    }
}
@Component
public class ClassA {
    private ApplicationContext context;

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    public void init() {
        System.out.println("Test 1 (Works):");
        context.getBean(ClassB.class);

        System.out.println("Test 2 (Not Working):");
        context.getBean(ClassB.class, this);

        System.out.println("Test 3 (Not Working):");
        new ClassB(this);
    }

    @TestAnnotation
    public void annotatedMethod() { }
}
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ClassB {
    private ClassA classA;

    @Autowired
    public ClassB(ClassA classA) {
        classA.annotatedMethod();
    }
}

with the following annotation and aspect:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
}
@Aspect
@Component
public class TestAnnotationAspect {
    private static final Logger log = LoggerFactory.getLogger(TestAnnotation.class);

    @Before("@annotation(test.sscce.aspect.TestAnnotation)")
    public void log(JoinPoint joinPoint) {
        System.out.println("OK");
    }
}

The advice for the test annotation is called only in the first case (printing "OK"), in the other two cases not. Why does it only work in the first case? Shouldn't "this" already refer to the proxied instance? It would be a much more consistent design, if all three cases would work. At least for the second case I would expect that it just works like the first case, as here it is possible to intercept and replace "this" with the proxied instance. Please correct me, if am wrong.

Thank you very much for your efforts.


No further details from SPR-15809

Comment From: spring-projects-issues

Alexandru-Constantin Bledea commented

Please see the documentation on understanding AOP proxies https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-understanding-aop-proxies

This is generally because 'this' is not the proxied instance but the target instance. It's the same reason why simply calling annotatedMethod() inside the target instance will not trigger the aop either. The target instance will not know that it's proxied.

Comment From: snicoll

Indeed, the two last calls provides the raw instance, not the one that has been decorated so that's the expected behavior.