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:
factory-bean-problem.zip
./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:
|
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:
|
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.
Affects: 6.0.0-RC2
We found this problem when testing Spring Boot's
JacksonTestersupport 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:factory-bean-problem.zip
./gradlew testshould result in two failures:The first reproduces the problem that we've seen in Spring Boot. If you edit
build.gradleto comment out the setting of thespring.aot.enabledsystem property and run./gradlew testagain,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 aBeanFactory.getTypecall:spring-framework/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
Lines 107 to 110 in 997dd3e
This is sufficient for the result of the check to be
trueand for autowiring to succeed.In the AOT-processed case, the target type is available from the bean definition:
spring-framework/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
Line 90 in 997dd3e
As a result, the
getTypecall on the bean factory never happens. The result of the check is false and autowiring fails.