Given a bean with @Lookup
, AopProxyUtils#ultimateTargetClass
can't get real target class because @Lookup
proxy does not have the necessary marker interface.
Comment From: jliu666
version 5.2.15.RELEASE.jar
Comment From: snicoll
Unfortunately, that's a bit too narrowed for us to investigate. You've described what you think is a problem but not how it actually occurs. If you want to pursue this, please share a small sample that we can run ourselves. You can do so by attaching a zip or pushing the code to a separate GitHub repository.
Comment From: sbrannen
Given a bean with
@Lookup
,AopProxyUtils#ultimateTargetClass
can't get real target class because@Lookup
proxy does not have the necessary marker interface.
That's by design.
As stated in the Javadoc for AopProxyUtils#ultimateTargetClass
:
Parameters: candidate the instance to check (might be an AOP proxy) Returns: the ultimate target class (or the plain class of the given object as fallback; never null)
The class created for a @Lookup
override is in fact generated by CGLIB; however, it is not a Spring AOP proxy.
A @Lookup
override class is created by CglibSubclassingInstantiationStrategy.CglibSubclassCreator
, not by a concrete implementation of org.springframework.aop.framework.AopProxy
.
Consequently, the class generated by CGLIB does not implement TargetClassAware
, Advised
, or SingletonTargetSource
.
So that's why AopProxyUtils#ultimateTargetClass
cannot find the ultimate target class for a @Lookup
override class.
Comment From: sbrannen
Please note that org.springframework.util.ClassUtils.getUserClass(Class<?>)
might actually be what you're looking for.
Comment From: leeychee
Recently, I got this issue too:
ClassUtils.isCglibProxy(testService) == true
but AopUtils.isCglibProxy(testService) == false
I know it's caused by what you mentioned before, but I have two questions:
- Is it correct behavior for
AopUtils.isCglibProxy
? Sometimes, I need to find the target class, but for this kind ofLookup
annotated class, should I always process separatedly? - Could you explain more about why not implement
SpringProxy
?
Here is the code. Thank you, @sbrannen
package org.fivej.bug.lookup_proxy;
import org.junit.jupiter.api.Test;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
public class NotSpringProxyWithLookupTest {
@Configuration
@ComponentScan
public static class Config {
}
@Component
public static class TestService {
@Lookup
public LookupService lookupService() {
return null;
}
}
@Component
@Scope("prototype")
public static class LookupService {
}
@Autowired
TestService testService;
@Test
void testServiceIsProxy() {
// FAILED
assertThat(AopUtils.isCglibProxy(testService)).isTrue();
}
@Test
void testServiceIsCglibProxy() {
// PASSED
assertThat(ClassUtils.isCglibProxy(testService)).isTrue();
}
}