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 de71971894..527aa30816 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.beans.factory; +import java.util.function.Consumer; import java.util.function.Supplier; import org.springframework.beans.BeansException; @@ -68,6 +69,22 @@ public interface ObjectProvider extends ObjectFactory { return (dependency != null ? dependency : defaultSupplier.get()); } + /** + * Consume an instance (possibly shared or independent) of the object + * managed by this factory, if available. + * @param dependencyConsumer a callback for processing the target object + * if available (not called otherwise) + * @throws BeansException in case of creation errors + * @since 5.0 + * @see #getIfAvailable() + */ + default void ifAvailable(Consumer dependencyConsumer) throws BeansException { + T dependency = getIfAvailable(); + if (dependency != null) { + dependencyConsumer.accept(dependency); + } + } + /** * Return an instance (possibly shared or independent) of the object * managed by this factory. @@ -96,4 +113,20 @@ public interface ObjectProvider extends ObjectFactory { return (dependency != null ? dependency : defaultSupplier.get()); } + /** + * Consume an instance (possibly shared or independent) of the object + * managed by this factory, if unique. + * @param dependencyConsumer a callback for processing the target object + * if unique (not called otherwise) + * @throws BeansException in case of creation errors + * @since 5.0 + * @see #getIfAvailable() + */ + default void ifUnique(Consumer dependencyConsumer) throws BeansException { + T dependency = getIfUnique(); + if (dependency != null) { + dependencyConsumer.accept(dependency); + } + } + } 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 2be178a41c..635883fa92 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 @@ -1297,8 +1297,10 @@ public class AutowiredAnnotationBeanPostProcessorTests { 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.consumeOptionalTestBean()); assertEquals(bf.getBean("testBean"), bean.getUniqueTestBean()); assertEquals(bf.getBean("testBean"), bean.getUniqueTestBeanWithDefault()); + assertEquals(bf.getBean("testBean"), bean.consumeUniqueTestBean()); bf.destroySingletons(); } @@ -1315,8 +1317,10 @@ public class AutowiredAnnotationBeanPostProcessorTests { assertSame(bf.getBean("testBean"), bean.getTestBean()); assertSame(bf.getBean("testBean"), bean.getOptionalTestBean()); assertSame(bf.getBean("testBean"), bean.getOptionalTestBeanWithDefault()); + assertEquals(bf.getBean("testBean"), bean.consumeOptionalTestBean()); assertSame(bf.getBean("testBean"), bean.getUniqueTestBean()); assertSame(bf.getBean("testBean"), bean.getUniqueTestBeanWithDefault()); + assertEquals(bf.getBean("testBean"), bean.consumeUniqueTestBean()); bf.destroySingletons(); } @@ -1337,9 +1341,11 @@ public class AutowiredAnnotationBeanPostProcessorTests { // expected } assertNull(bean.getOptionalTestBean()); + assertNull(bean.consumeOptionalTestBean()); assertEquals(new TestBean("default"), bean.getOptionalTestBeanWithDefault()); assertEquals(new TestBean("default"), bean.getUniqueTestBeanWithDefault()); assertNull(bean.getUniqueTestBean()); + assertNull(bean.consumeUniqueTestBean()); bf.destroySingletons(); } @@ -1368,7 +1374,15 @@ public class AutowiredAnnotationBeanPostProcessorTests { catch (NoUniqueBeanDefinitionException ex) { // expected } + try { + bean.consumeOptionalTestBean(); + fail("Should have thrown NoUniqueBeanDefinitionException"); + } + catch (NoUniqueBeanDefinitionException ex) { + // expected + } assertNull(bean.getUniqueTestBean()); + assertNull(bean.consumeUniqueTestBean()); bf.destroySingletons(); } @@ -1389,7 +1403,9 @@ public class AutowiredAnnotationBeanPostProcessorTests { SmartObjectFactoryInjectionBean bean = (SmartObjectFactoryInjectionBean) bf.getBean("annotatedBean"); assertSame(bf.getBean("testBean1"), bean.getTestBean()); assertSame(bf.getBean("testBean1"), bean.getOptionalTestBean()); + assertSame(bf.getBean("testBean1"), bean.consumeOptionalTestBean()); assertSame(bf.getBean("testBean1"), bean.getUniqueTestBean()); + assertSame(bf.getBean("testBean1"), bean.consumeUniqueTestBean()); assertFalse(bf.containsSingleton("testBean2")); bf.destroySingletons(); } @@ -3020,6 +3036,8 @@ public class AutowiredAnnotationBeanPostProcessorTests { @Autowired private ObjectProvider testBeanFactory; + private TestBean consumedTestBean; + public TestBean getTestBean() { return this.testBeanFactory.getObject(); } @@ -3036,6 +3054,11 @@ public class AutowiredAnnotationBeanPostProcessorTests { return this.testBeanFactory.getIfAvailable(() -> new TestBean("default")); } + public TestBean consumeOptionalTestBean() { + this.testBeanFactory.ifAvailable(tb -> consumedTestBean = tb); + return consumedTestBean; + } + public TestBean getUniqueTestBean() { return this.testBeanFactory.getIfUnique(); } @@ -3043,6 +3066,11 @@ public class AutowiredAnnotationBeanPostProcessorTests { public TestBean getUniqueTestBeanWithDefault() { return this.testBeanFactory.getIfUnique(() -> new TestBean("default")); } + + public TestBean consumeUniqueTestBean() { + this.testBeanFactory.ifUnique(tb -> consumedTestBean = tb); + return consumedTestBean; + } }