KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > factory > BeanFactoryUtils


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.factory;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Arrays JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.springframework.beans.BeansException;
27 import org.springframework.util.Assert;
28 import org.springframework.util.StringUtils;
29
30 /**
31  * Convenience methods operating on bean factories, in particular on the
32  * ListableBeanFactory interface.
33  *
34  * <p>Returns bean counts, bean names or bean instances,
35  * taking into account the nesting hierarchy of a bean factory
36  * (which the methods defined on the ListableBeanFactory interface don't,
37  * in contrast to the methods defined on the BeanFactory interface).
38  *
39  * @author Rod Johnson
40  * @author Juergen Hoeller
41  * @since 04.07.2003
42  * @see ListableBeanFactory
43  */

44 public abstract class BeanFactoryUtils {
45
46     /**
47      * Separator for generated bean names. If a class name or parent name is not
48      * unique, "#1", "#2" etc will be appended, until the name becomes unique.
49      */

50     public static final String JavaDoc GENERATED_BEAN_NAME_SEPARATOR = "#";
51
52
53     /**
54      * Return whether the given name is a factory dereference
55      * (beginning with the factory dereference prefix).
56      * @see BeanFactory#FACTORY_BEAN_PREFIX
57      */

58     public static boolean isFactoryDereference(String JavaDoc name) {
59         return name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX);
60     }
61
62     /**
63      * Return the actual bean name, stripping out the factory dereference prefix
64      * (if any).
65      * @see BeanFactory#FACTORY_BEAN_PREFIX
66      */

67     public static String JavaDoc transformedBeanName(String JavaDoc name) {
68         Assert.notNull(name, "'name' must not be null");
69         return (name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX) ?
70                 name.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()) : name);
71     }
72
73     /**
74      * Extract the "raw" bean name from the given (potentially generated) bean name,
75      * excluding any "#..." suffixes which might have been added for uniqueness.
76      * @param name the potentially generated bean name
77      * @return the raw bean name
78      * @see #GENERATED_BEAN_NAME_SEPARATOR
79      */

80     public static String JavaDoc originalBeanName(String JavaDoc name) {
81         Assert.notNull(name, "'name' must not be null");
82         int separatorIndex = name.indexOf(GENERATED_BEAN_NAME_SEPARATOR);
83         return (separatorIndex != -1 ? name.substring(0, separatorIndex) : name);
84     }
85
86
87     /**
88      * Count all beans in any hierarchy in which this factory participates.
89      * Includes counts of ancestor bean factories.
90      * <p>Beans that are "overridden" (specified in a descendant factory
91      * with the same name) are only counted once.
92      * @param lbf the bean factory
93      * @return count of beans including those defined in ancestor factories
94      */

95     public static int countBeansIncludingAncestors(ListableBeanFactory lbf) {
96         return beanNamesIncludingAncestors(lbf).length;
97     }
98     
99     /**
100      * Return all bean names in the factory, including ancestor factories.
101      * @param lbf the bean factory
102      * @return the array of matching bean names, or an empty array if none
103      * @see #beanNamesForTypeIncludingAncestors
104      */

105     public static String JavaDoc[] beanNamesIncludingAncestors(ListableBeanFactory lbf) {
106         return beanNamesForTypeIncludingAncestors(lbf, Object JavaDoc.class);
107     }
108
109
110     /**
111      * Get all bean names for the given type, including those defined in ancestor
112      * factories. Will return unique names in case of overridden bean definitions.
113      * <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
114      * will get initialized. If the object created by the FactoryBean doesn't match,
115      * the raw FactoryBean itself will be matched against the type.
116      * <p>This version of <code>beanNamesForTypeIncludingAncestors</code> automatically
117      * includes prototypes and FactoryBeans.
118      * @param lbf the bean factory
119      * @param type the type that beans must match
120      * @return the array of matching bean names, or an empty array if none
121      */

122     public static String JavaDoc[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class JavaDoc type) {
123         Assert.notNull(lbf, "ListableBeanFactory must not be null");
124         String JavaDoc[] result = lbf.getBeanNamesForType(type);
125         if (lbf instanceof HierarchicalBeanFactory) {
126             HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
127             if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
128                 String JavaDoc[] parentResult = beanNamesForTypeIncludingAncestors(
129                         (ListableBeanFactory) hbf.getParentBeanFactory(), type);
130                 List JavaDoc resultList = new ArrayList JavaDoc();
131                 resultList.addAll(Arrays.asList(result));
132                 for (int i = 0; i < parentResult.length; i++) {
133                     String JavaDoc beanName = parentResult[i];
134                     if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
135                         resultList.add(beanName);
136                     }
137                 }
138                 result = StringUtils.toStringArray(resultList);
139             }
140         }
141         return result;
142     }
143
144     /**
145      * Get all bean names for the given type, including those defined in ancestor
146      * factories. Will return unique names in case of overridden bean definitions.
147      * <p>Does consider objects created by FactoryBeans if the "allowEagerInit"
148      * flag is set, which means that FactoryBeans will get initialized. If the
149      * object created by the FactoryBean doesn't match, the raw FactoryBean itself
150      * will be matched against the type. If "allowEagerInit" is not set,
151      * only raw FactoryBeans will be checked (which doesn't require initialization
152      * of each FactoryBean).
153      * @param lbf the bean factory
154      * @param includePrototypes whether to include prototype beans too or just singletons
155      * (also applies to FactoryBeans)
156      * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
157      * <i>objects created by FactoryBeans</i> (or by factory methods with a
158      * "factory-bean" reference) for the type check. Note that FactoryBeans need to be
159      * eagerly initialized to determine their type: So be aware that passing in "true"
160      * for this flag will initialize FactoryBeans and "factory-bean" references.
161      * @param type the type that beans must match
162      * @return the array of matching bean names, or an empty array if none
163      */

164     public static String JavaDoc[] beanNamesForTypeIncludingAncestors(
165             ListableBeanFactory lbf, Class JavaDoc type, boolean includePrototypes, boolean allowEagerInit) {
166
167         Assert.notNull(lbf, "ListableBeanFactory must not be null");
168         String JavaDoc[] result = lbf.getBeanNamesForType(type, includePrototypes, allowEagerInit);
169         if (lbf instanceof HierarchicalBeanFactory) {
170             HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
171             if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
172                 String JavaDoc[] parentResult = beanNamesForTypeIncludingAncestors(
173                         (ListableBeanFactory) hbf.getParentBeanFactory(), type, includePrototypes, allowEagerInit);
174                 List JavaDoc resultList = new ArrayList JavaDoc();
175                 resultList.addAll(Arrays.asList(result));
176                 for (int i = 0; i < parentResult.length; i++) {
177                     String JavaDoc beanName = parentResult[i];
178                     if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
179                         resultList.add(beanName);
180                     }
181                 }
182                 result = StringUtils.toStringArray(resultList);
183             }
184         }
185         return result;
186     }
187
188     /**
189      * Return all beans of the given type or subtypes, also picking up beans defined in
190      * ancestor bean factories if the current bean factory is a HierarchicalBeanFactory.
191      * The returned Map will only contain beans of this type.
192      * <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
193      * will get initialized. If the object created by the FactoryBean doesn't match,
194      * the raw FactoryBean itself will be matched against the type.
195      * @param lbf the bean factory
196      * @param type type of bean to match
197      * @return the Map of matching bean instances, or an empty Map if none
198      * @throws BeansException if a bean could not be created
199      */

200     public static Map JavaDoc beansOfTypeIncludingAncestors(ListableBeanFactory lbf, Class JavaDoc type)
201         throws BeansException {
202
203         Assert.notNull(lbf, "ListableBeanFactory must not be null");
204         Map JavaDoc result = new HashMap JavaDoc();
205         result.putAll(lbf.getBeansOfType(type));
206         if (lbf instanceof HierarchicalBeanFactory) {
207             HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
208             if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
209                 Map JavaDoc parentResult = beansOfTypeIncludingAncestors(
210                         (ListableBeanFactory) hbf.getParentBeanFactory(), type);
211                 for (Iterator JavaDoc it = parentResult.entrySet().iterator(); it.hasNext();) {
212                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
213                     String JavaDoc beanName = (String JavaDoc) entry.getKey();
214                     if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
215                         result.put(beanName, entry.getValue());
216                     }
217                 }
218             }
219         }
220         return result;
221     }
222
223     /**
224      * Return all beans of the given type or subtypes, also picking up beans defined in
225      * ancestor bean factories if the current bean factory is a HierarchicalBeanFactory.
226      * The returned Map will only contain beans of this type.
227      * <p>Does consider objects created by FactoryBeans if the "allowEagerInit"
228      * flag is set, which means that FactoryBeans will get initialized. If the
229      * object created by the FactoryBean doesn't match, the raw FactoryBean itself
230      * will be matched against the type. If "allowEagerInit" is not set,
231      * only raw FactoryBeans will be checked (which doesn't require initialization
232      * of each FactoryBean).
233      * @param lbf the bean factory
234      * @param type type of bean to match
235      * @param includePrototypes whether to include prototype beans too or just singletons
236      * (also applies to FactoryBeans)
237      * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
238      * <i>objects created by FactoryBeans</i> (or by factory methods with a
239      * "factory-bean" reference) for the type check. Note that FactoryBeans need to be
240      * eagerly initialized to determine their type: So be aware that passing in "true"
241      * for this flag will initialize FactoryBeans and "factory-bean" references.
242      * @return the Map of matching bean instances, or an empty Map if none
243      * @throws BeansException if a bean could not be created
244      */

245     public static Map JavaDoc beansOfTypeIncludingAncestors(
246             ListableBeanFactory lbf, Class JavaDoc type, boolean includePrototypes, boolean allowEagerInit)
247         throws BeansException {
248
249         Assert.notNull(lbf, "ListableBeanFactory must not be null");
250         Map JavaDoc result = new HashMap JavaDoc();
251         result.putAll(lbf.getBeansOfType(type, includePrototypes, allowEagerInit));
252         if (lbf instanceof HierarchicalBeanFactory) {
253             HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
254             if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
255                 Map JavaDoc parentResult = beansOfTypeIncludingAncestors(
256                         (ListableBeanFactory) hbf.getParentBeanFactory(), type, includePrototypes, allowEagerInit);
257                 for (Iterator JavaDoc it = parentResult.entrySet().iterator(); it.hasNext();) {
258                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
259                     String JavaDoc beanName = (String JavaDoc) entry.getKey();
260                     if (!result.containsKey(beanName) && !hbf.containsLocalBean(beanName)) {
261                         result.put(beanName, entry.getValue());
262                     }
263                 }
264             }
265         }
266         return result;
267     }
268
269
270     /**
271      * Return a single bean of the given type or subtypes, also picking up beans
272      * defined in ancestor bean factories if the current bean factory is a
273      * HierarchicalBeanFactory. Useful convenience method when we expect a
274      * single bean and don't care about the bean name.
275      * <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
276      * will get initialized. If the object created by the FactoryBean doesn't match,
277      * the raw FactoryBean itself will be matched against the type.
278      * <p>This version of <code>beanOfTypeIncludingAncestors</code> automatically includes
279      * prototypes and FactoryBeans.
280      * @param lbf the bean factory
281      * @param type type of bean to match
282      * @return the matching bean instance
283      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
284      * if 0 or more than 1 beans of the given type were found
285      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
286      * if no single bean could be found for the given type
287      * @throws BeansException if the bean could not be created
288      */

289     public static Object JavaDoc beanOfTypeIncludingAncestors(ListableBeanFactory lbf, Class JavaDoc type)
290             throws BeansException {
291
292         Map JavaDoc beansOfType = beansOfTypeIncludingAncestors(lbf, type);
293         if (beansOfType.size() == 1) {
294             return beansOfType.values().iterator().next();
295         }
296         else {
297             throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
298         }
299     }
300
301     /**
302      * Return a single bean of the given type or subtypes, also picking up beans
303      * defined in ancestor bean factories if the current bean factory is a
304      * HierarchicalBeanFactory. Useful convenience method when we expect a
305      * single bean and don't care about the bean name.
306      * <p>Does consider objects created by FactoryBeans if the "allowEagerInit"
307      * flag is set, which means that FactoryBeans will get initialized. If the
308      * object created by the FactoryBean doesn't match, the raw FactoryBean itself
309      * will be matched against the type. If "allowEagerInit" is not set,
310      * only raw FactoryBeans will be checked (which doesn't require initialization
311      * of each FactoryBean).
312      * @param lbf the bean factory
313      * @param type type of bean to match
314      * @param includePrototypes whether to include prototype beans too or just singletons
315      * (also applies to FactoryBeans)
316      * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
317      * <i>objects created by FactoryBeans</i> (or by factory methods with a
318      * "factory-bean" reference) for the type check. Note that FactoryBeans need to be
319      * eagerly initialized to determine their type: So be aware that passing in "true"
320      * for this flag will initialize FactoryBeans and "factory-bean" references.
321      * @return the matching bean instance
322      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
323      * if 0 or more than 1 beans of the given type were found
324      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
325      * if no single bean could be found for the given type
326      * @throws BeansException if the bean could not be created
327      */

328     public static Object JavaDoc beanOfTypeIncludingAncestors(
329             ListableBeanFactory lbf, Class JavaDoc type, boolean includePrototypes, boolean allowEagerInit)
330         throws BeansException {
331
332         Map JavaDoc beansOfType = beansOfTypeIncludingAncestors(lbf, type, includePrototypes, allowEagerInit);
333         if (beansOfType.size() == 1) {
334             return beansOfType.values().iterator().next();
335         }
336         else {
337             throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
338         }
339     }
340
341     /**
342      * Return a single bean of the given type or subtypes, not looking in ancestor
343      * factories. Useful convenience method when we expect a single bean and
344      * don't care about the bean name.
345      * <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
346      * will get initialized. If the object created by the FactoryBean doesn't match,
347      * the raw FactoryBean itself will be matched against the type.
348      * <p>This version of <code>beanOfType</code> automatically includes
349      * prototypes and FactoryBeans.
350      * @param lbf the bean factory
351      * @param type type of bean to match
352      * @return the matching bean instance
353      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
354      * if 0 or more than 1 beans of the given type were found
355      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
356      * if no single bean could be found for the given type
357      * @throws BeansException if the bean could not be created
358      */

359     public static Object JavaDoc beanOfType(ListableBeanFactory lbf, Class JavaDoc type) throws BeansException {
360         Assert.notNull(lbf, "ListableBeanFactory must not be null");
361         Map JavaDoc beansOfType = lbf.getBeansOfType(type);
362         if (beansOfType.size() == 1) {
363             return beansOfType.values().iterator().next();
364         }
365         else {
366             throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
367         }
368     }
369
370     /**
371      * Return a single bean of the given type or subtypes, not looking in ancestor
372      * factories. Useful convenience method when we expect a single bean and
373      * don't care about the bean name.
374      * <p>Does consider objects created by FactoryBeans if the "allowEagerInit"
375      * flag is set, which means that FactoryBeans will get initialized. If the
376      * object created by the FactoryBean doesn't match, the raw FactoryBean itself
377      * will be matched against the type. If "allowEagerInit" is not set,
378      * only raw FactoryBeans will be checked (which doesn't require initialization
379      * of each FactoryBean).
380      * @param lbf the bean factory
381      * @param type type of bean to match
382      * @param includePrototypes whether to include prototype beans too or just singletons
383      * (also applies to FactoryBeans)
384      * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
385      * <i>objects created by FactoryBeans</i> (or by factory methods with a
386      * "factory-bean" reference) for the type check. Note that FactoryBeans need to be
387      * eagerly initialized to determine their type: So be aware that passing in "true"
388      * for this flag will initialize FactoryBeans and "factory-bean" references.
389      * @return the matching bean instance
390      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
391      * if 0 or more than 1 beans of the given type were found
392      * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
393      * if no single bean could be found for the given type
394      * @throws BeansException if the bean could not be created
395      */

396     public static Object JavaDoc beanOfType(
397             ListableBeanFactory lbf, Class JavaDoc type, boolean includePrototypes, boolean allowEagerInit)
398         throws BeansException {
399
400         Assert.notNull(lbf, "ListableBeanFactory must not be null");
401         Map JavaDoc beansOfType = lbf.getBeansOfType(type, includePrototypes, allowEagerInit);
402         if (beansOfType.size() == 1) {
403             return beansOfType.values().iterator().next();
404         }
405         else {
406             throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
407         }
408     }
409
410 }
411
Popular Tags