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..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 @@ -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 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 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(); + } + private Consumer methodParameterDeclaredOn( Class expected) { return declaredOn( @@ -4346,4 +4367,34 @@ public class AutowiredAnnotationBeanPostProcessorTests { } } + + static class MixedNullableInjectionBean { + + @Nullable + public Integer nullableBean; + + public String nonNullBean; + + @Autowired(required = false) + public void nullabilityInjection(@Nullable Integer nullableBean, String nonNullBean) { + this.nullableBean = nullableBean; + this.nonNullBean = nonNullBean; + } + } + + + static class MixedOptionalInjectionBean { + + @Nullable + public Integer nullableBean; + + public String nonNullBean; + + @Autowired(required = false) + public void optionalInjection(Optional optionalBean, String nonNullBean) { + optionalBean.ifPresent(bean -> this.nullableBean = bean); + this.nonNullBean = nonNullBean; + } + } + }