From 32c0540424da2c9d79923f587ef660d594f2f521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=85=B6=E8=8B=97?= Date: Wed, 25 Mar 2020 10:26:05 +0800 Subject: [PATCH 1/2] Improve @Autowired method injection on mixed nullability args See gh-17215 --- .../AutowiredAnnotationBeanPostProcessor.java | 2 +- ...wiredAnnotationBeanPostProcessorTests.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index c5d9e11624b..75f932757f2 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -865,7 +865,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA descriptors[i] = currDesc; try { Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeanNames, typeConverter); - if (arg == null && !this.required) { + if (arg == null && !this.required && !methodParam.isOptional()) { arguments = null; break; } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index f76705de4af..8340fcfdeeb 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -32,6 +32,7 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.SortedMap; @@ -2600,6 +2601,26 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertThat(bean.testBean).isSameAs(bf.getBean("annotatedBean")); } + @Test + public void testMethodInjectionWithMultiMixedNullableArgs(){ + bf.registerBeanDefinition("nonNullBean", new RootBeanDefinition( + NonNullBean.class)); + bf.registerBeanDefinition("mixedNullableInjectionBean", new RootBeanDefinition(MixedNullableInjectionBean.class)); + MixedNullableInjectionBean mixedNullableInjectionBean = bf.getBean(MixedNullableInjectionBean.class); + assertThat(mixedNullableInjectionBean.nonNullBean).isNotNull(); + assertThat(mixedNullableInjectionBean.nullableBean).isNull(); + } + + @Test + public void testMethodInjectionWithMultiMixedOptionalArgs(){ + bf.registerBeanDefinition("nonNullBean", new RootBeanDefinition( + NonNullBean.class)); + bf.registerBeanDefinition("mixedOptionalInjectionBean", new RootBeanDefinition(MixedOptionalInjectionBean.class)); + MixedOptionalInjectionBean mixedOptionalInjectionBean = bf.getBean(MixedOptionalInjectionBean.class); + assertThat(mixedOptionalInjectionBean.nonNullBean).isNotNull(); + assertThat(mixedOptionalInjectionBean.nullableBean).isNull(); + } + private Consumer methodParameterDeclaredOn( Class expected) { return declaredOn( @@ -4346,4 +4367,35 @@ public class AutowiredAnnotationBeanPostProcessorTests { } } + static class NullableBean { + + } + static class NonNullBean { + + } + + static class MixedNullableInjectionBean{ + public NonNullBean nonNullBean; + public NullableBean nullableBean; + + @Autowired(required = false) + public void nullabilityInjection(@Nullable NullableBean nullableBean, NonNullBean nonNullBean){ + if(nullableBean != null){ + this.nullableBean = nullableBean; + } + this.nonNullBean = nonNullBean; + } + } + + static class MixedOptionalInjectionBean{ + public NonNullBean nonNullBean; + public NullableBean nullableBean; + + @Autowired(required = false) + public void optionalInjection(Optional optionalBean, NonNullBean nonNullBean){ + optionalBean.ifPresent(bean -> this.nullableBean = bean); + this.nonNullBean = nonNullBean; + } + } + } From 8efc7a958e7cf6101aadc2edd8dfdf7d9028a212 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Aug 2023 12:45:44 +0200 Subject: [PATCH 2/2] Polish "Improve @Autowired method injection on mixed nullability args" See gh-17215 --- ...wiredAnnotationBeanPostProcessorTests.java | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index 8340fcfdeeb..46b6653d1f8 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -2602,20 +2602,20 @@ public class AutowiredAnnotationBeanPostProcessorTests { } @Test - public void testMethodInjectionWithMultiMixedNullableArgs(){ - bf.registerBeanDefinition("nonNullBean", new RootBeanDefinition( - NonNullBean.class)); - bf.registerBeanDefinition("mixedNullableInjectionBean", new RootBeanDefinition(MixedNullableInjectionBean.class)); + public void mixedNullableArgMethodInjection(){ + bf.registerSingleton("nonNullBean", "Test"); + bf.registerBeanDefinition("mixedNullableInjectionBean", + new RootBeanDefinition(MixedNullableInjectionBean.class)); MixedNullableInjectionBean mixedNullableInjectionBean = bf.getBean(MixedNullableInjectionBean.class); assertThat(mixedNullableInjectionBean.nonNullBean).isNotNull(); assertThat(mixedNullableInjectionBean.nullableBean).isNull(); } @Test - public void testMethodInjectionWithMultiMixedOptionalArgs(){ - bf.registerBeanDefinition("nonNullBean", new RootBeanDefinition( - NonNullBean.class)); - bf.registerBeanDefinition("mixedOptionalInjectionBean", new RootBeanDefinition(MixedOptionalInjectionBean.class)); + public void mixedOptionalArgMethodInjection(){ + bf.registerSingleton("nonNullBean", "Test"); + bf.registerBeanDefinition("mixedOptionalInjectionBean", + new RootBeanDefinition(MixedOptionalInjectionBean.class)); MixedOptionalInjectionBean mixedOptionalInjectionBean = bf.getBean(MixedOptionalInjectionBean.class); assertThat(mixedOptionalInjectionBean.nonNullBean).isNotNull(); assertThat(mixedOptionalInjectionBean.nullableBean).isNull(); @@ -4367,32 +4367,31 @@ public class AutowiredAnnotationBeanPostProcessorTests { } } - static class NullableBean { - } - static class NonNullBean { + static class MixedNullableInjectionBean { - } + @Nullable + public Integer nullableBean; - static class MixedNullableInjectionBean{ - public NonNullBean nonNullBean; - public NullableBean nullableBean; + public String nonNullBean; @Autowired(required = false) - public void nullabilityInjection(@Nullable NullableBean nullableBean, NonNullBean nonNullBean){ - if(nullableBean != null){ - this.nullableBean = nullableBean; - } + public void nullabilityInjection(@Nullable Integer nullableBean, String nonNullBean) { + this.nullableBean = nullableBean; this.nonNullBean = nonNullBean; } } - static class MixedOptionalInjectionBean{ - public NonNullBean nonNullBean; - public NullableBean nullableBean; + + static class MixedOptionalInjectionBean { + + @Nullable + public Integer nullableBean; + + public String nonNullBean; @Autowired(required = false) - public void optionalInjection(Optional optionalBean, NonNullBean nonNullBean){ + public void optionalInjection(Optional optionalBean, String nonNullBean) { optionalBean.ifPresent(bean -> this.nullableBean = bean); this.nonNullBean = nonNullBean; }