From da4b539f20705af7de49d47d63feedcf7a44680d Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 9 Nov 2022 12:00:34 +0100 Subject: [PATCH] Stop generating generic type as Object for unresolved generics Closes gh-29454 --- .../aot/ResolvableTypeCodeGenerator.java | 2 +- .../ApplicationContextAotGeneratorTests.java | 14 +++++++++ .../annotation/AutowiredGenericTemplate.java | 30 +++++++++++++++++++ .../context/annotation/GenericTemplate.java | 23 ++++++++++++++ .../GenericTemplateConfiguration.java | 30 +++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/AutowiredGenericTemplate.java create mode 100644 spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplate.java create mode 100644 spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplateConfiguration.java diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/ResolvableTypeCodeGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/ResolvableTypeCodeGenerator.java index e259af65b8a9..e7b715dd006c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/ResolvableTypeCodeGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/ResolvableTypeCodeGenerator.java @@ -45,7 +45,7 @@ private static CodeBlock generateCode(ResolvableType resolvableType, boolean all return CodeBlock.of("$T.NONE", ResolvableType.class); } Class type = ClassUtils.getUserClass(resolvableType.toClass()); - if (resolvableType.hasGenerics()) { + if (resolvableType.hasGenerics() && !resolvableType.hasUnresolvableGenerics()) { return generateCodeWithGenerics(resolvableType, type); } if (allowClassResult) { diff --git a/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java b/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java index bdf218c04e88..bbd4a1effdab 100644 --- a/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java +++ b/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java @@ -54,8 +54,10 @@ import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver; import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.testfixture.context.annotation.AutowiredComponent; +import org.springframework.context.testfixture.context.annotation.AutowiredGenericTemplate; import org.springframework.context.testfixture.context.annotation.CglibConfiguration; import org.springframework.context.testfixture.context.annotation.ConfigurableCglibConfiguration; +import org.springframework.context.testfixture.context.annotation.GenericTemplateConfiguration; import org.springframework.context.testfixture.context.annotation.InitDestroyComponent; import org.springframework.context.testfixture.context.annotation.LazyAutowiredFieldComponent; import org.springframework.context.testfixture.context.annotation.LazyAutowiredMethodComponent; @@ -114,6 +116,18 @@ void processAheadOfTimeWhenHasAutowiring() { }); } + @Test + void processAheadOfTimeWhenHasAutowiringOnUnresolvedGeneric() { + GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext(); + applicationContext.registerBean(GenericTemplateConfiguration.class); + applicationContext.registerBean("autowiredComponent", AutowiredGenericTemplate.class); + testCompiledResult(applicationContext, (initializer, compiled) -> { + GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer); + AutowiredGenericTemplate bean = freshApplicationContext.getBean(AutowiredGenericTemplate.class); + assertThat(bean).hasFieldOrPropertyWithValue("genericTemplate", applicationContext.getBean("genericTemplate")); + }); + } + @Test void processAheadOfTimeWhenHasLazyAutowiringOnField() { testAutowiredComponent(LazyAutowiredFieldComponent.class, (bean, generationContext) -> { diff --git a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/AutowiredGenericTemplate.java b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/AutowiredGenericTemplate.java new file mode 100644 index 000000000000..8862451ba9ca --- /dev/null +++ b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/AutowiredGenericTemplate.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.testfixture.context.annotation; + +import org.springframework.beans.factory.annotation.Autowired; + +public class AutowiredGenericTemplate { + + private GenericTemplate genericTemplate; + + @Autowired + public void setGenericTemplate(GenericTemplate genericTemplate) { + this.genericTemplate = genericTemplate; + } + +} diff --git a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplate.java b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplate.java new file mode 100644 index 000000000000..d3fe98baf56d --- /dev/null +++ b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplate.java @@ -0,0 +1,23 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.testfixture.context.annotation; + +public interface GenericTemplate { + + void process(V item); + +} diff --git a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplateConfiguration.java b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplateConfiguration.java new file mode 100644 index 000000000000..938a5263275b --- /dev/null +++ b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/context/annotation/GenericTemplateConfiguration.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.testfixture.context.annotation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +public class GenericTemplateConfiguration { + + @Bean + public GenericTemplate genericTemplate() { + return v -> {}; + } + +}