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; + } + } + }