0

I've hit an issue where adding an annotation to a class produces a proxy error

Bean named 'XXXX' is expected to be of type 'xxxx.XXXX' but was actually of type 'com.sun.proxy.$Proxy223'

For further details see How to enabled CGLIB proxies on @Component?

I'm trying to understand when Java will decided to create a JDK or CGLIB proxy. I understand it's meant to create JDK proxies when there's an interface and CGLIB proxies otherwise. Plus SpringBoot 2.0+ is meant to always use CGLIB proxies. See https://www.springcloud.io/post/2022-01/springboot-aop/#gsc.tab=0

However in my case I'm getting a JDK proxy when there is no interface. As such I'd like to figure out where the code makes this decision in order to debug it.

Potentially this is done by a implementation of AbstractAdvisorAutoProxyCreator. But actually finding the point at which the decision is taken is time consuming. Even with a debugger at hand.

Any pointers?

Shane Gannon
  • 6,770
  • 7
  • 41
  • 64
  • `I understand it's meant to create JDK proxies when there's an interface and CGLIB proxies otherwise` - that is not correct, however not far from the truth. The Q: is it possible to create CGLIB proxy if target class is final? – Andrey B. Panfilov Aug 20 '22 at 11:18
  • In this case the class was not `final`. It does have a `static final` class field. – Shane Gannon Aug 21 '22 at 08:25

1 Answers1

0

I found, hidden away in our Configuration hierarchy, the following bean definition.

@Bean
public AnnotationAwareAspectJAutoProxyCreator aspectJProxyCreator() {
    return new AnnotationAwareAspectJAutoProxyCreator();
}

This appears to be the source of the problem. Which is impressive as my Component named XXXX is not an interface and does not implement one. i.e. That means a JDK proxy should not be used.

If I switch the bean definition over to

@Bean
public AnnotationAwareAspectJAutoProxyCreator aspectJProxyCreator() {
    var a = new AnnotationAwareAspectJAutoProxyCreator();
    // Fixes the problem
    a.setProxyTargetClass(true);
    return a;
}

A CGLIB proxy is instead created. A better solution would be to remove this bean entirely, which I'm investigating.

Shane Gannon
  • 6,770
  • 7
  • 41
  • 64