001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory; 018 019import java.util.Iterator; 020import java.util.function.Consumer; 021import java.util.function.Supplier; 022import java.util.stream.Stream; 023 024import org.springframework.beans.BeansException; 025import org.springframework.lang.Nullable; 026 027/** 028 * A variant of {@link ObjectFactory} designed specifically for injection points, 029 * allowing for programmatic optionality and lenient not-unique handling. 030 * 031 * <p>As of 5.1, this interface extends {@link Iterable} and provides {@link Stream} 032 * support. It can be therefore be used in {@code for} loops, provides {@link #forEach} 033 * iteration and allows for collection-style {@link #stream} access. 034 * 035 * @author Juergen Hoeller 036 * @since 4.3 037 * @param <T> the object type 038 * @see BeanFactory#getBeanProvider 039 * @see org.springframework.beans.factory.annotation.Autowired 040 */ 041public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> { 042 043 /** 044 * Return an instance (possibly shared or independent) of the object 045 * managed by this factory. 046 * <p>Allows for specifying explicit construction arguments, along the 047 * lines of {@link BeanFactory#getBean(String, Object...)}. 048 * @param args arguments to use when creating a corresponding instance 049 * @return an instance of the bean 050 * @throws BeansException in case of creation errors 051 * @see #getObject() 052 */ 053 T getObject(Object... args) throws BeansException; 054 055 /** 056 * Return an instance (possibly shared or independent) of the object 057 * managed by this factory. 058 * @return an instance of the bean, or {@code null} if not available 059 * @throws BeansException in case of creation errors 060 * @see #getObject() 061 */ 062 @Nullable 063 T getIfAvailable() throws BeansException; 064 065 /** 066 * Return an instance (possibly shared or independent) of the object 067 * managed by this factory. 068 * @param defaultSupplier a callback for supplying a default object 069 * if none is present in the factory 070 * @return an instance of the bean, or the supplied default object 071 * if no such bean is available 072 * @throws BeansException in case of creation errors 073 * @since 5.0 074 * @see #getIfAvailable() 075 */ 076 default T getIfAvailable(Supplier<T> defaultSupplier) throws BeansException { 077 T dependency = getIfAvailable(); 078 return (dependency != null ? dependency : defaultSupplier.get()); 079 } 080 081 /** 082 * Consume an instance (possibly shared or independent) of the object 083 * managed by this factory, if available. 084 * @param dependencyConsumer a callback for processing the target object 085 * if available (not called otherwise) 086 * @throws BeansException in case of creation errors 087 * @since 5.0 088 * @see #getIfAvailable() 089 */ 090 default void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException { 091 T dependency = getIfAvailable(); 092 if (dependency != null) { 093 dependencyConsumer.accept(dependency); 094 } 095 } 096 097 /** 098 * Return an instance (possibly shared or independent) of the object 099 * managed by this factory. 100 * @return an instance of the bean, or {@code null} if not available or 101 * not unique (i.e. multiple candidates found with none marked as primary) 102 * @throws BeansException in case of creation errors 103 * @see #getObject() 104 */ 105 @Nullable 106 T getIfUnique() throws BeansException; 107 108 /** 109 * Return an instance (possibly shared or independent) of the object 110 * managed by this factory. 111 * @param defaultSupplier a callback for supplying a default object 112 * if no unique candidate is present in the factory 113 * @return an instance of the bean, or the supplied default object 114 * if no such bean is available or if it is not unique in the factory 115 * (i.e. multiple candidates found with none marked as primary) 116 * @throws BeansException in case of creation errors 117 * @since 5.0 118 * @see #getIfUnique() 119 */ 120 default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException { 121 T dependency = getIfUnique(); 122 return (dependency != null ? dependency : defaultSupplier.get()); 123 } 124 125 /** 126 * Consume an instance (possibly shared or independent) of the object 127 * managed by this factory, if unique. 128 * @param dependencyConsumer a callback for processing the target object 129 * if unique (not called otherwise) 130 * @throws BeansException in case of creation errors 131 * @since 5.0 132 * @see #getIfAvailable() 133 */ 134 default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException { 135 T dependency = getIfUnique(); 136 if (dependency != null) { 137 dependencyConsumer.accept(dependency); 138 } 139 } 140 141 /** 142 * Return an {@link Iterator} over all matching object instances, 143 * without specific ordering guarantees (but typically in registration order). 144 * @since 5.1 145 * @see #stream() 146 */ 147 @Override 148 default Iterator<T> iterator() { 149 return stream().iterator(); 150 } 151 152 /** 153 * Return a sequential {@link Stream} over all matching object instances, 154 * without specific ordering guarantees (but typically in registration order). 155 * @since 5.1 156 * @see #iterator() 157 * @see #orderedStream() 158 */ 159 default Stream<T> stream() { 160 throw new UnsupportedOperationException("Multi element access not supported"); 161 } 162 163 /** 164 * Return a sequential {@link Stream} over all matching object instances, 165 * pre-ordered according to the factory's common order comparator. 166 * <p>In a standard Spring application context, this will be ordered 167 * according to {@link org.springframework.core.Ordered} conventions, 168 * and in case of annotation-based configuration also considering the 169 * {@link org.springframework.core.annotation.Order} annotation, 170 * analogous to multi-element injection points of list/array type. 171 * @since 5.1 172 * @see #stream() 173 * @see org.springframework.core.OrderComparator 174 */ 175 default Stream<T> orderedStream() { 176 throw new UnsupportedOperationException("Ordered element access not supported"); 177 } 178 179}