-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
Affects: 6.0.0-RC2
We found this problem when testing Spring Boot's JacksonTester
support but I believe it's a general AOT problem to do with factory beans that produce a generic type. Here's a small sample that reproduces the problem:
./gradlew test
should result in two failures:
> Task :test FAILED
FactoryBeanProblemApplicationTests > contextLoads() FAILED
org.springframework.beans.factory.UnsatisfiedDependencyException at AutowiredAnnotationBeanPostProcessor.java:744
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException at DefaultListableBeanFactory.java:1782
MinimalReproductionTests > aotConfig() FAILED
org.springframework.beans.factory.UnsatisfiedDependencyException at MinimalReproductionTests.java:46
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException at MinimalReproductionTests.java:46
The first reproduces the problem that we've seen in Spring Boot. If you edit build.gradle
to comment out the setting of the spring.aot.enabled
system property and run ./gradlew test
again, contextLoads()
should pass. The second is an attempt to reproduce the problem in a minimal (and slightly simplified) manner. It doesn't involve Boot or the Test Framework at all.
From what I have seen in the debugger, the behavior diverges in GenericTypeAwareAutowireCandidateResolver.checkGenericTypeMatch(BeanDefinitionHolder, DependencyDescriptor)
. In the Java config case, the target type is determined via a BeanFactory.getType
call:
Lines 107 to 110 in 997dd3e
if (targetType == null) { | |
// Regular case: straight bean instance, with BeanFactory available. | |
if (this.beanFactory != null) { | |
Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName()); |
This is sufficient for the result of the check to be true
and for autowiring to succeed.
In the AOT-processed case, the target type is available from the bean definition:
Line 90 in 997dd3e
targetType = rbd.targetType; |
As a result, the getType
call on the bean factory never happens. The result of the check is false and autowiring fails.