diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java index ffa2683e31..7bc61f87f7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java @@ -16,6 +16,8 @@ package org.springframework.beans.factory; +import java.util.function.Supplier; + import org.springframework.beans.BeansException; /** @@ -48,6 +50,22 @@ public interface ObjectProvider extends ObjectFactory { */ T getIfAvailable() throws BeansException; + /** + * Return an instance (possibly shared or independent) of the object + * managed by this factory. + * @param defaultSupplier a callback for supplying a default object + * if none is present in the factory + * @return an instance of the bean, or the supplied default object + * if no such bean is available + * @throws BeansException in case of creation errors + * @since 5.0 + * @see #getIfAvailable() + */ + default T getIfAvailable(Supplier defaultSupplier) throws BeansException { + T dependency = getIfAvailable(); + return (dependency != null ? dependency : defaultSupplier.get()); + } + /** * Return an instance (possibly shared or independent) of the object * managed by this factory. @@ -58,4 +76,21 @@ public interface ObjectProvider extends ObjectFactory { */ T getIfUnique() throws BeansException; + /** + * Return an instance (possibly shared or independent) of the object + * managed by this factory. + * @param defaultSupplier a callback for supplying a default object + * if no unique candidate is present in the factory + * @return an instance of the bean, or the supplied default object + * if no such bean is available or if it is not unique in the factory + * (i.e. multiple candidates found with none marked as primary) + * @throws BeansException in case of creation errors + * @since 5.0 + * @see #getIfUnique() + */ + default T getIfUnique(Supplier defaultSupplier) throws BeansException { + T dependency = getIfUnique(); + return (dependency != null ? dependency : defaultSupplier.get()); + } + } 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 9efc993097..45f7896991 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 @@ -1137,7 +1137,9 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertEquals(bf.getBean("testBean"), bean.getTestBean()); assertEquals(bf.getBean("testBean", "myName"), bean.getTestBean("myName")); assertEquals(bf.getBean("testBean"), bean.getOptionalTestBean()); + assertEquals(bf.getBean("testBean"), bean.getOptionalTestBeanWithDefault()); assertEquals(bf.getBean("testBean"), bean.getUniqueTestBean()); + assertEquals(bf.getBean("testBean"), bean.getUniqueTestBeanWithDefault()); bf.destroySingletons(); } @@ -1153,7 +1155,9 @@ public class AutowiredAnnotationBeanPostProcessorTests { SmartObjectFactoryInjectionBean bean = (SmartObjectFactoryInjectionBean) bf.getBean("annotatedBean"); assertSame(bf.getBean("testBean"), bean.getTestBean()); assertSame(bf.getBean("testBean"), bean.getOptionalTestBean()); + assertSame(bf.getBean("testBean"), bean.getOptionalTestBeanWithDefault()); assertSame(bf.getBean("testBean"), bean.getUniqueTestBean()); + assertSame(bf.getBean("testBean"), bean.getUniqueTestBeanWithDefault()); bf.destroySingletons(); } @@ -1174,6 +1178,8 @@ public class AutowiredAnnotationBeanPostProcessorTests { // expected } assertNull(bean.getOptionalTestBean()); + assertEquals(new TestBean("default"), bean.getOptionalTestBeanWithDefault()); + assertEquals(new TestBean("default"), bean.getUniqueTestBeanWithDefault()); assertNull(bean.getUniqueTestBean()); bf.destroySingletons(); } @@ -2732,9 +2738,17 @@ public class AutowiredAnnotationBeanPostProcessorTests { return this.testBeanFactory.getIfAvailable(); } + public TestBean getOptionalTestBeanWithDefault() { + return this.testBeanFactory.getIfAvailable(() -> new TestBean("default")); + } + public TestBean getUniqueTestBean() { return this.testBeanFactory.getIfUnique(); } + + public TestBean getUniqueTestBeanWithDefault() { + return this.testBeanFactory.getIfUnique(() -> new TestBean("default")); + } }