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.Arrays;
020import java.util.Collection;
021
022import org.springframework.core.ResolvableType;
023import org.springframework.lang.Nullable;
024import org.springframework.util.StringUtils;
025
026/**
027 * Exception thrown when a {@code BeanFactory} is asked for a bean instance for which
028 * multiple matching candidates have been found when only one matching bean was expected.
029 *
030 * @author Juergen Hoeller
031 * @since 3.2.1
032 * @see BeanFactory#getBean(Class)
033 */
034@SuppressWarnings("serial")
035public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionException {
036
037        private final int numberOfBeansFound;
038
039        @Nullable
040        private final Collection<String> beanNamesFound;
041
042
043        /**
044         * Create a new {@code NoUniqueBeanDefinitionException}.
045         * @param type required type of the non-unique bean
046         * @param numberOfBeansFound the number of matching beans
047         * @param message detailed message describing the problem
048         */
049        public NoUniqueBeanDefinitionException(Class<?> type, int numberOfBeansFound, String message) {
050                super(type, message);
051                this.numberOfBeansFound = numberOfBeansFound;
052                this.beanNamesFound = null;
053        }
054
055        /**
056         * Create a new {@code NoUniqueBeanDefinitionException}.
057         * @param type required type of the non-unique bean
058         * @param beanNamesFound the names of all matching beans (as a Collection)
059         */
060        public NoUniqueBeanDefinitionException(Class<?> type, Collection<String> beanNamesFound) {
061                super(type, "expected single matching bean but found " + beanNamesFound.size() + ": " +
062                                StringUtils.collectionToCommaDelimitedString(beanNamesFound));
063                this.numberOfBeansFound = beanNamesFound.size();
064                this.beanNamesFound = beanNamesFound;
065        }
066
067        /**
068         * Create a new {@code NoUniqueBeanDefinitionException}.
069         * @param type required type of the non-unique bean
070         * @param beanNamesFound the names of all matching beans (as an array)
071         */
072        public NoUniqueBeanDefinitionException(Class<?> type, String... beanNamesFound) {
073                this(type, Arrays.asList(beanNamesFound));
074        }
075
076        /**
077         * Create a new {@code NoUniqueBeanDefinitionException}.
078         * @param type required type of the non-unique bean
079         * @param beanNamesFound the names of all matching beans (as a Collection)
080         * @since 5.1
081         */
082        public NoUniqueBeanDefinitionException(ResolvableType type, Collection<String> beanNamesFound) {
083                super(type, "expected single matching bean but found " + beanNamesFound.size() + ": " +
084                                StringUtils.collectionToCommaDelimitedString(beanNamesFound));
085                this.numberOfBeansFound = beanNamesFound.size();
086                this.beanNamesFound = beanNamesFound;
087        }
088
089        /**
090         * Create a new {@code NoUniqueBeanDefinitionException}.
091         * @param type required type of the non-unique bean
092         * @param beanNamesFound the names of all matching beans (as an array)
093         * @since 5.1
094         */
095        public NoUniqueBeanDefinitionException(ResolvableType type, String... beanNamesFound) {
096                this(type, Arrays.asList(beanNamesFound));
097        }
098
099
100        /**
101         * Return the number of beans found when only one matching bean was expected.
102         * For a NoUniqueBeanDefinitionException, this will usually be higher than 1.
103         * @see #getBeanType()
104         */
105        @Override
106        public int getNumberOfBeansFound() {
107                return this.numberOfBeansFound;
108        }
109
110        /**
111         * Return the names of all beans found when only one matching bean was expected.
112         * Note that this may be {@code null} if not specified at construction time.
113         * @since 4.3
114         * @see #getBeanType()
115         */
116        @Nullable
117        public Collection<String> getBeanNamesFound() {
118                return this.beanNamesFound;
119        }
120
121}