KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > context > access > ContextSingletonBeanFactoryLocator


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.context.access;
18
19 import java.util.HashMap JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.springframework.beans.BeansException;
23 import org.springframework.beans.factory.BeanFactory;
24 import org.springframework.beans.factory.access.BeanFactoryLocator;
25 import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
26 import org.springframework.context.ConfigurableApplicationContext;
27 import org.springframework.context.support.ClassPathXmlApplicationContext;
28 import org.springframework.core.io.support.ResourcePatternResolver;
29 import org.springframework.core.io.support.ResourcePatternUtils;
30
31 /**
32  * <p>Variant of SingletonBeanFactoryLocator which creates its internal bean
33  * factory reference definition as an ApplicationContext instead of
34  * SingletonBeanFactoryLocator's BeanFactory. For almost all usage scenarios, this
35  * will not make a difference, since within that ApplicationContext or BeanFactory
36  * you are still free to create either BeanFactories or ApplicationContexts. The
37  * main reason one would need to use this class is if bean post-processing (or other
38  * ApplicationContext specific features are needed in the bean reference definition
39  * itself).
40  *
41  * <p><strong>Note:</strong> This class uses <strong>classpath*:beanRefContext.xml</strong>
42  * as the default name for the bean factory reference definition. It is not possible
43  * nor legal to share definitions with SingletonBeanFactoryLocator at the same time.
44  *
45  * @author Colin Sampaleanu
46  * @author Juergen Hoeller
47  * @see org.springframework.context.access.DefaultLocatorFactory
48  */

49 public class ContextSingletonBeanFactoryLocator extends SingletonBeanFactoryLocator {
50
51     private static final String JavaDoc BEANS_REFS_XML_NAME = "classpath*:beanRefContext.xml";
52     
53     // the keyed singleton instances
54
private static final Map JavaDoc instances = new HashMap JavaDoc();
55
56
57     /**
58      * Returns an instance which uses the default "classpath*:beanRefContext.xml", as
59      * the name of the definition file(s). All resources returned by the current
60      * thread's context class loader's <code>getResources</code> method with this
61      * name will be combined to create a definition, which is just a BeanFactory.
62      */

63     public static BeanFactoryLocator getInstance() throws BeansException {
64         return getInstance(BEANS_REFS_XML_NAME);
65     }
66
67     /**
68      * Returns an instance which uses the the specified selector, as the name of the
69      * definition file(s). In the case of a name with a Spring "classpath*:" prefix,
70      * or with no prefix, which is treated the same, the current thread's context class
71      * loader's <code>getResources</code> method will be called with this value to get
72      * all resources having that name. These resources will then be combined to form a
73      * definition. In the case where the name uses a Spring "classpath:" prefix, or
74      * a standard URL prefix, then only one resource file will be loaded as the
75      * definition.
76      * @param selector the name of the resource(s) which will be read and combine to
77      * form the definition for the SingletonBeanFactoryLocator instance. The one file
78      * or multiple fragments with this name must form a valid ApplicationContext
79      * definition.
80      */

81     public static BeanFactoryLocator getInstance(String JavaDoc selector) throws BeansException {
82         // For backwards compatibility, we prepend "classpath*:" to the selector name if there
83
// is no other prefix (i.e. "classpath*:", "classpath:", or some URL prefix).
84
if (!ResourcePatternUtils.isUrl(selector)) {
85             selector = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + selector;
86         }
87
88         synchronized (instances) {
89             if (logger.isTraceEnabled()) {
90                 logger.trace("ContextSingletonBeanFactoryLocator.getInstance(): instances.hashCode=" +
91                         instances.hashCode() + ", instances=" + instances);
92             }
93             BeanFactoryLocator bfl = (BeanFactoryLocator) instances.get(selector);
94             if (bfl == null) {
95                 bfl = new ContextSingletonBeanFactoryLocator(selector);
96                 instances.put(selector, bfl);
97             }
98             return bfl;
99         }
100     }
101
102
103     /**
104      * Constructor which uses the default "classpath*:beanRefContext.xml", as the name of the
105      * definition file(s). All resources returned by the definition classloader's
106      * getResources() method with this name will be combined to create a definition.
107      */

108     protected ContextSingletonBeanFactoryLocator() {
109         super(BEANS_REFS_XML_NAME);
110     }
111
112     /**
113      * Constructor which uses the the specified name as the name of the definition file(s).
114      * All resources returned by the definition ClassLoader's <code>getResources</code>
115      * method with this name will be combined to create a definition.
116      */

117     protected ContextSingletonBeanFactoryLocator(String JavaDoc resourceName) {
118         super(resourceName);
119     }
120
121     /**
122      * Overrides default method to create definition object as an ApplicationContext
123      * instead of the default BeanFactory. This does not affect what can actually
124      * be loaded by that definition.
125      */

126     protected BeanFactory createDefinition(String JavaDoc resourceName, String JavaDoc factoryKey) throws BeansException {
127         return new ClassPathXmlApplicationContext(new String JavaDoc[] {resourceName}, false);
128     }
129
130     /**
131      * Overrides default method to initialize definition object, which this method
132      * assumes is a ConfigurableApplicationContext. This implementation simply invokes
133      * {@link ConfigurableApplicationContext#refresh ConfigurableApplicationContext.refresh()}.
134      */

135     protected void initializeDefinition(BeanFactory groupDef) throws BeansException {
136         if (groupDef instanceof ConfigurableApplicationContext) {
137             ((ConfigurableApplicationContext) groupDef).refresh();
138         }
139     }
140
141     /**
142      * Overrides default method to work with an ApplicationContext.
143      */

144     protected void destroyDefinition(BeanFactory groupDef, String JavaDoc resourceName) throws BeansException {
145         if (groupDef instanceof ConfigurableApplicationContext) {
146             if (logger.isTraceEnabled()) {
147                 logger.trace("ContextSingletonBeanFactoryLocator group with resourceName '" +
148                         resourceName + "' being released, as there are no more references");
149             }
150             ((ConfigurableApplicationContext) groupDef).close();
151         }
152     }
153
154 }
155
Popular Tags