diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java index ba38b589326..89245691cd9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java @@ -78,7 +78,7 @@ class BeanDefinitionMethodGenerator { List aotContributions) { RootBeanDefinition mbd = registeredBean.getMergedBeanDefinition(); - if (mbd.getInstanceSupplier() != null) { + if (mbd.getInstanceSupplier() != null && aotContributions.isEmpty()) { throw new IllegalArgumentException("Code generation is not supported for bean definitions declaring an instance supplier callback : " + mbd); } this.methodGeneratorFactory = methodGeneratorFactory; diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java index a6c71312f75..a530c81a102 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java @@ -105,6 +105,23 @@ class BeanDefinitionMethodGeneratorTests { }); } + @Test // gh-29556 + void generateBeanDefinitionMethodGeneratesMethodWithInstanceSupplier() { + RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class, TestBean::new)); + BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator( + this.methodGeneratorFactory, registeredBean, null, + List.of((generationContext, beanRegistrationCode) -> { })); + MethodReference method = generator.generateBeanDefinitionMethod( + this.generationContext, this.beanRegistrationsCode); + compile(method, (actual, compiled) -> { + SourceFile sourceFile = compiled.getSourceFile(".*BeanDefinitions"); + assertThat(sourceFile).contains("Get the bean definition for 'testBean'"); + assertThat(sourceFile).contains("beanType = TestBean.class"); + assertThat(sourceFile).contains("setInstanceSupplier(TestBean::new)"); + assertThat(actual).isInstanceOf(RootBeanDefinition.class); + }); + } + @Test void generateBeanDefinitionMethodWhenHasInnerClassTargetMethodGeneratesMethod() { this.beanFactory.registerBeanDefinition("testBeanConfiguration", new RootBeanDefinition( @@ -493,8 +510,8 @@ class BeanDefinitionMethodGeneratorTests { testBeanDefinitionMethodInCurrentFile(Boolean.class, beanDefinition); } - @Test - void throwExceptionWithInstanceSupplier() { + @Test // gh-29556 + void throwExceptionWithInstanceSupplierWithoutAotContribution() { RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class, TestBean::new)); assertThatIllegalArgumentException().isThrownBy(() -> new BeanDefinitionMethodGenerator( this.methodGeneratorFactory, registeredBean, null,