Avoid double proxying for @Resource @Lazy fallback autowiring
Includes refactored @Resource resolver for AOT with lazy resolution support. Closes gh-31447 See gh-29614
This commit is contained in:
@@ -142,7 +142,7 @@ class CommonAnnotationBeanRegistrationAotContributionTests {
|
||||
postProcessor.apply(registeredBean, instance);
|
||||
assertThat(instance).extracting("one").isEqualTo("1");
|
||||
assertThat(getSourceFile(compiled, PrivateMethodResourceSample.class))
|
||||
.contains("resolveAndInvoke(");
|
||||
.contains("resolveAndSet(");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class CommonAnnotationBeanRegistrationAotContributionTests {
|
||||
postProcessor.apply(registeredBean, instance);
|
||||
assertThat(instance).extracting("text").isEqualTo("1");
|
||||
assertThat(getSourceFile(compiled, PrivateMethodResourceWithCustomNameSample.class))
|
||||
.contains("resolveAndInvoke(");
|
||||
.contains("resolveAndSet(");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ class CommonAnnotationBeanRegistrationAotContributionTests {
|
||||
postProcessor.apply(registeredBean, instance);
|
||||
assertThat(instance).extracting("one").isEqualTo("1");
|
||||
assertThat(getSourceFile(compiled, PackagePrivateMethodResourceFromParentSample.class))
|
||||
.contains("resolveAndInvoke(");
|
||||
.contains("resolveAndSet(");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.aot;
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -30,11 +30,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceFieldValueResolver}.
|
||||
* Tests for {@code ResourceFieldValueResolver}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ResourceFieldValueResolverTests {
|
||||
class ResourceElementResolverFieldTests {
|
||||
|
||||
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@@ -43,8 +43,7 @@ class ResourceFieldValueResolverTests {
|
||||
void resolveWhenFieldIsMissingThrowsException() {
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> ResourceFieldValueResolver.forField("missing")
|
||||
.resolve(registeredBean))
|
||||
.isThrownBy(() -> ResourceElementResolver.forField("missing").resolve(registeredBean))
|
||||
.withMessage("No field 'missing' found on " + TestBean.class.getName());
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ class ResourceFieldValueResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
Object resolved = ResourceFieldValueResolver.forField("one")
|
||||
Object resolved = ResourceElementResolver.forField("one")
|
||||
.resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("1");
|
||||
}
|
||||
@@ -63,8 +62,7 @@ class ResourceFieldValueResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
Object resolved = ResourceFieldValueResolver.forField("test", "two")
|
||||
.resolve(registeredBean);
|
||||
Object resolved = ResourceElementResolver.forField("test", "two").resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("2");
|
||||
}
|
||||
|
||||
@@ -72,8 +70,7 @@ class ResourceFieldValueResolverTests {
|
||||
void resolveWheNoMatchFallbackOnType() {
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
Object resolved = ResourceFieldValueResolver.forField("one")
|
||||
.resolve(registeredBean);
|
||||
Object resolved = ResourceElementResolver.forField("one").resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("2");
|
||||
}
|
||||
|
||||
@@ -82,9 +79,8 @@ class ResourceFieldValueResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceFieldValueResolver.forField("test")
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(NoUniqueBeanDefinitionException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forField("test").resolve(registeredBean))
|
||||
.isInstanceOf(NoUniqueBeanDefinitionException.class)
|
||||
.hasMessageContaining(String.class.getName())
|
||||
.hasMessageContaining("one").hasMessageContaining("two");
|
||||
}
|
||||
@@ -92,9 +88,8 @@ class ResourceFieldValueResolverTests {
|
||||
@Test
|
||||
void resolveWhenNoCandidateMatchingTypeThrowsException() {
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceFieldValueResolver.forField("test")
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(NoSuchBeanDefinitionException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forField("test").resolve(registeredBean))
|
||||
.isInstanceOf(NoSuchBeanDefinitionException.class)
|
||||
.hasMessageContaining(String.class.getName());
|
||||
}
|
||||
|
||||
@@ -102,9 +97,8 @@ class ResourceFieldValueResolverTests {
|
||||
void resolveWhenInvalidMatchingTypeThrowsException() {
|
||||
this.beanFactory.registerSingleton("count", "counter");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceFieldValueResolver.forField("count")
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(BeanNotOfRequiredTypeException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forField("count").resolve(registeredBean))
|
||||
.isInstanceOf(BeanNotOfRequiredTypeException.class)
|
||||
.hasMessageContaining(Integer.class.getName())
|
||||
.hasMessageContaining(String.class.getName());
|
||||
}
|
||||
@@ -114,8 +108,7 @@ class ResourceFieldValueResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
TestBean testBean = new TestBean();
|
||||
ResourceFieldValueResolver.forField("one").resolveAndSet(registeredBean,
|
||||
testBean);
|
||||
ResourceElementResolver.forField("one").resolveAndSet(registeredBean, testBean);
|
||||
assertThat(testBean.one).isEqualTo("1");
|
||||
}
|
||||
|
||||
@@ -123,16 +116,16 @@ class ResourceFieldValueResolverTests {
|
||||
void resolveRegistersDependantBeans() {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
ResourceFieldValueResolver.forField("one").resolve(registeredBean);
|
||||
ResourceElementResolver.forField("one").resolve(registeredBean);
|
||||
assertThat(this.beanFactory.getDependentBeans("one")).containsExactly("testBean");
|
||||
}
|
||||
|
||||
private RegisteredBean registerTestBean(DefaultListableBeanFactory beanFactory) {
|
||||
beanFactory.registerBeanDefinition("testBean",
|
||||
new RootBeanDefinition(TestBean.class));
|
||||
beanFactory.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||
return RegisteredBean.of(beanFactory, "testBean");
|
||||
}
|
||||
|
||||
|
||||
static class TestBean {
|
||||
|
||||
String one;
|
||||
@@ -140,7 +133,6 @@ class ResourceFieldValueResolverTests {
|
||||
String test;
|
||||
|
||||
Integer count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.aot;
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -32,18 +32,19 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceMethodArgumentResolver}/
|
||||
* Tests for {@code ResourceMethodArgumentResolver}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ResourceMethodArgumentResolverTests {
|
||||
class ResourceElementResolverMethodTests {
|
||||
|
||||
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
@Test
|
||||
void resolveWhenMethodIsMissingThrowsException() {
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
ResourceMethodArgumentResolver resolver = ResourceMethodArgumentResolver.forMethod("missing", InputStream.class);
|
||||
ResourceElementResolver resolver = ResourceElementResolver.forMethod("missing", InputStream.class);
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.resolve(registeredBean))
|
||||
.withMessage("Method 'missing' with parameter type 'java.io.InputStream' declared on %s could not be found.",
|
||||
@@ -55,8 +56,7 @@ class ResourceMethodArgumentResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
ResourceMethodArgumentResolver resolver = ResourceMethodArgumentResolver
|
||||
.forMethod("setOne", String.class);
|
||||
ResourceElementResolver resolver = ResourceElementResolver.forMethod("setOne", String.class);
|
||||
Object resolved = resolver.resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("1");
|
||||
}
|
||||
@@ -66,8 +66,7 @@ class ResourceMethodArgumentResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
Object resolved = ResourceMethodArgumentResolver.forMethod("setTest", String.class, "two")
|
||||
.resolve(registeredBean);
|
||||
Object resolved = ResourceElementResolver.forMethod("setTest", String.class, "two").resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("2");
|
||||
}
|
||||
|
||||
@@ -75,8 +74,7 @@ class ResourceMethodArgumentResolverTests {
|
||||
void resolveWheNoMatchFallbackOnType() {
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
Object resolved = ResourceMethodArgumentResolver.forMethod("setOne", String.class)
|
||||
.resolve(registeredBean);
|
||||
Object resolved = ResourceElementResolver.forMethod("setOne", String.class).resolve(registeredBean);
|
||||
assertThat(resolved).isEqualTo("2");
|
||||
}
|
||||
|
||||
@@ -85,9 +83,8 @@ class ResourceMethodArgumentResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
this.beanFactory.registerSingleton("two", "2");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceMethodArgumentResolver.forMethod("setTest", String.class)
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(NoUniqueBeanDefinitionException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forMethod("setTest", String.class).resolve(registeredBean))
|
||||
.isInstanceOf(NoUniqueBeanDefinitionException.class)
|
||||
.hasMessageContaining(String.class.getName())
|
||||
.hasMessageContaining("one").hasMessageContaining("two");
|
||||
}
|
||||
@@ -95,9 +92,8 @@ class ResourceMethodArgumentResolverTests {
|
||||
@Test
|
||||
void resolveWhenNoCandidateMatchingTypeThrowsException() {
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceMethodArgumentResolver.forMethod("setTest", String.class)
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(NoSuchBeanDefinitionException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forMethod("setTest", String.class).resolve(registeredBean))
|
||||
.isInstanceOf(NoSuchBeanDefinitionException.class)
|
||||
.hasMessageContaining(String.class.getName());
|
||||
}
|
||||
|
||||
@@ -105,9 +101,8 @@ class ResourceMethodArgumentResolverTests {
|
||||
void resolveWhenInvalidMatchingTypeThrowsException() {
|
||||
this.beanFactory.registerSingleton("count", "counter");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
assertThatThrownBy(() -> ResourceMethodArgumentResolver.forMethod("setCount", Integer.class)
|
||||
.resolve(registeredBean)
|
||||
).isInstanceOf(BeanNotOfRequiredTypeException.class)
|
||||
assertThatThrownBy(() -> ResourceElementResolver.forMethod("setCount", Integer.class).resolve(registeredBean))
|
||||
.isInstanceOf(BeanNotOfRequiredTypeException.class)
|
||||
.hasMessageContaining(Integer.class.getName())
|
||||
.hasMessageContaining(String.class.getName());
|
||||
}
|
||||
@@ -117,8 +112,7 @@ class ResourceMethodArgumentResolverTests {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
TestBean testBean = new TestBean();
|
||||
ResourceMethodArgumentResolver.forMethod("setOne", String.class)
|
||||
.resolveAndInvoke(registeredBean, testBean);
|
||||
ResourceElementResolver.forMethod("setOne", String.class).resolveAndSet(registeredBean, testBean);
|
||||
assertThat(testBean.one).isEqualTo("1");
|
||||
}
|
||||
|
||||
@@ -126,13 +120,12 @@ class ResourceMethodArgumentResolverTests {
|
||||
void resolveRegistersDependantBeans() {
|
||||
this.beanFactory.registerSingleton("one", "1");
|
||||
RegisteredBean registeredBean = registerTestBean(this.beanFactory);
|
||||
ResourceMethodArgumentResolver.forMethod("setOne", String.class).resolve(registeredBean);
|
||||
ResourceElementResolver.forMethod("setOne", String.class).resolve(registeredBean);
|
||||
assertThat(this.beanFactory.getDependentBeans("one")).containsExactly("testBean");
|
||||
}
|
||||
|
||||
private RegisteredBean registerTestBean(DefaultListableBeanFactory beanFactory) {
|
||||
beanFactory.registerBeanDefinition("testBean",
|
||||
new RootBeanDefinition(TestBean.class));
|
||||
beanFactory.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||
return RegisteredBean.of(beanFactory, "testBean");
|
||||
}
|
||||
|
||||
@@ -156,7 +149,6 @@ class ResourceMethodArgumentResolverTests {
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -253,7 +252,6 @@ class ApplicationContextAotGeneratorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("gh-31447")
|
||||
void processAheadOfTimeWhenHasLazyResourceAutowiringOnField() {
|
||||
testResourceAutowiringComponent(LazyResourceFieldComponent.class, (bean, generationContext) -> {
|
||||
Environment environment = bean.getEnvironment();
|
||||
|
||||
Reference in New Issue
Block a user