Source Code Cross Referenced for DefaultSingletonBeanRegistry.java in  » J2EE » spring-framework-2.0.6 » org » springframework » beans » factory » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.beans.factory.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 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:         *      http://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:
017:        package org.springframework.beans.factory.support;
018:
019:        import java.util.Collections;
020:        import java.util.HashMap;
021:        import java.util.HashSet;
022:        import java.util.Iterator;
023:        import java.util.Map;
024:        import java.util.Set;
025:
026:        import org.apache.commons.logging.Log;
027:        import org.apache.commons.logging.LogFactory;
028:
029:        import org.springframework.beans.factory.BeanCreationNotAllowedException;
030:        import org.springframework.beans.factory.BeanCurrentlyInCreationException;
031:        import org.springframework.beans.factory.DisposableBean;
032:        import org.springframework.beans.factory.ObjectFactory;
033:        import org.springframework.beans.factory.config.SingletonBeanRegistry;
034:        import org.springframework.core.CollectionFactory;
035:        import org.springframework.util.Assert;
036:        import org.springframework.util.StringUtils;
037:
038:        /**
039:         * Generic registry for shared bean instances, implementing the
040:         * {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
041:         * Allows for registering singleton instances that should be shared
042:         * for all callers of the registry, to be obtained via bean name.
043:         *
044:         * <p>Also supports registration of
045:         * {@link org.springframework.beans.factory.DisposableBean} instances,
046:         * (which might or might not correspond to registered singletons),
047:         * to be destroyed on shutdown of the registry. Dependencies between
048:         * beans can be registered to enforce an appropriate shutdown order.
049:         *
050:         * <p>This class mainly serves as base class for
051:         * {@link org.springframework.beans.factory.BeanFactory} implementations,
052:         * factoring out the common management of singleton bean instances. Note that
053:         * the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
054:         * interface extends the {@link SingletonBeanRegistry} interface.
055:         *
056:         * <p>Note that this class assumes neither a bean definition concept
057:         * nor a specific creation process for bean instances, in contrast to
058:         * {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
059:         * (which inherit from it). Can alternatively also be used as a nested
060:         * helper to delegate to.
061:         *
062:         * @author Juergen Hoeller
063:         * @since 2.0
064:         * @see #registerSingleton
065:         * @see #registerDisposableBean
066:         * @see org.springframework.beans.factory.DisposableBean
067:         * @see org.springframework.beans.factory.config.ConfigurableBeanFactory
068:         */
069:        public class DefaultSingletonBeanRegistry implements 
070:                SingletonBeanRegistry {
071:
072:            /**
073:             * Internal marker for a null singleton object:
074:             * used as marker value for concurrent Maps (which don't support null values).
075:             */
076:            private static final Object NULL_OBJECT = new Object();
077:
078:            /** Logger available to subclasses */
079:            protected final Log logger = LogFactory.getLog(getClass());
080:
081:            /** Cache of singleton objects: bean name --> bean instance */
082:            private final Map singletonObjects = CollectionFactory
083:                    .createConcurrentMapIfPossible(16);
084:
085:            /** Set of registered singletons, containing the bean names in registration order */
086:            private final Set registeredSingletons = CollectionFactory
087:                    .createLinkedSetIfPossible(16);
088:
089:            /** Names of beans that are currently in creation */
090:            private final Set singletonsCurrentlyInCreation = Collections
091:                    .synchronizedSet(new HashSet());
092:
093:            /** Flag that indicates whether we're currently within destroySingletons */
094:            private boolean singletonsCurrentlyInDestruction = false;
095:
096:            /** Disposable bean instances: bean name --> disposable instance */
097:            private final Map disposableBeans = CollectionFactory
098:                    .createLinkedMapIfPossible(16);
099:
100:            /** Map between dependent bean names: bean name --> dependent bean name */
101:            private final Map dependentBeanMap = new HashMap();
102:
103:            public void registerSingleton(String beanName,
104:                    Object singletonObject) throws IllegalStateException {
105:                Assert.notNull(beanName, "'beanName' must not be null");
106:                synchronized (this .singletonObjects) {
107:                    Object oldObject = this .singletonObjects.get(beanName);
108:                    if (oldObject != null) {
109:                        throw new IllegalStateException(
110:                                "Could not register object [" + singletonObject
111:                                        + "] under bean name '" + beanName
112:                                        + "': there is already object ["
113:                                        + oldObject + "] bound");
114:                    }
115:                    addSingleton(beanName, singletonObject);
116:                }
117:            }
118:
119:            /**
120:             * Add the given singleton object to the singleton cache of this factory.
121:             * <p>To be called for eager registration of singletons, e.g. to be able to
122:             * resolve circular references.
123:             * @param beanName the name of the bean
124:             * @param singletonObject the singleton object
125:             */
126:            protected void addSingleton(String beanName, Object singletonObject) {
127:                synchronized (this .singletonObjects) {
128:                    this .singletonObjects.put(beanName,
129:                            (singletonObject != null ? singletonObject
130:                                    : NULL_OBJECT));
131:                    this .registeredSingletons.add(beanName);
132:                }
133:            }
134:
135:            public Object getSingleton(String beanName) {
136:                Assert.notNull(beanName, "'beanName' must not be null");
137:                Object singletonObject = this .singletonObjects.get(beanName);
138:                return (singletonObject != NULL_OBJECT ? singletonObject : null);
139:            }
140:
141:            /**
142:             * Return the (raw) singleton object registered under the given name,
143:             * creating and registering a new one if none registered yet.
144:             * @param beanName the name of the bean
145:             * @param singletonFactory the ObjectFactory to lazily create the singleton
146:             * with, if necessary
147:             * @return the registered singleton object
148:             */
149:            public Object getSingleton(String beanName,
150:                    ObjectFactory singletonFactory) {
151:                Assert.notNull(beanName, "'beanName' must not be null");
152:                synchronized (this .singletonObjects) {
153:                    // Re-check singleton cache within synchronized block.
154:                    Object singletonObject = this .singletonObjects
155:                            .get(beanName);
156:                    if (singletonObject == null) {
157:                        if (this .singletonsCurrentlyInDestruction) {
158:                            throw new BeanCreationNotAllowedException(
159:                                    beanName,
160:                                    "Singleton bean creation not allowed while the singletons of this factory are in destruction "
161:                                            + "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
162:                        }
163:                        if (logger.isDebugEnabled()) {
164:                            logger
165:                                    .debug("Creating shared instance of singleton bean '"
166:                                            + beanName + "'");
167:                        }
168:                        beforeSingletonCreation(beanName);
169:                        try {
170:                            singletonObject = singletonFactory.getObject();
171:                        } finally {
172:                            afterSingletonCreation(beanName);
173:                        }
174:                        addSingleton(beanName, singletonObject);
175:                    }
176:                    return (singletonObject != NULL_OBJECT ? singletonObject
177:                            : null);
178:                }
179:            }
180:
181:            /**
182:             * Remove the bean with the given name from the singleton cache of this factory.
183:             * <p>To be able to clean up eager registration of a singleton if creation failed.
184:             * @param beanName the name of the bean
185:             */
186:            protected void removeSingleton(String beanName) {
187:                Assert.notNull(beanName, "'beanName' must not be null");
188:                this .singletonObjects.remove(beanName);
189:                this .registeredSingletons.remove(beanName);
190:            }
191:
192:            public boolean containsSingleton(String beanName) {
193:                Assert.notNull(beanName, "'beanName' must not be null");
194:                return (this .singletonObjects.containsKey(beanName));
195:            }
196:
197:            public String[] getSingletonNames() {
198:                synchronized (this .singletonObjects) {
199:                    return StringUtils.toStringArray(this .registeredSingletons);
200:                }
201:            }
202:
203:            public int getSingletonCount() {
204:                synchronized (this .singletonObjects) {
205:                    return this .registeredSingletons.size();
206:                }
207:            }
208:
209:            /**
210:             * Callback before singleton creation.
211:             * <p>Default implementation register the singleton as currently in creation.
212:             * @param beanName the name of the singleton about to be created
213:             * @see #isSingletonCurrentlyInCreation
214:             */
215:            protected void beforeSingletonCreation(String beanName) {
216:                if (!this .singletonsCurrentlyInCreation.add(beanName)) {
217:                    throw new BeanCurrentlyInCreationException(beanName);
218:                }
219:            }
220:
221:            /**
222:             * Callback after singleton creation.
223:             * <p>Default implementation marks the singleton as not in creation anymore.
224:             * @param beanName the name of the singleton that has been created
225:             * @see #isSingletonCurrentlyInCreation
226:             */
227:            protected void afterSingletonCreation(String beanName) {
228:                if (!this .singletonsCurrentlyInCreation.remove(beanName)) {
229:                    throw new IllegalStateException("Singleton '" + beanName
230:                            + "' isn't currently in creation");
231:                }
232:            }
233:
234:            /**
235:             * Return whether the specified singleton bean is currently in creation
236:             * (within the entire factory).
237:             * @param beanName the name of the bean
238:             */
239:            public final boolean isSingletonCurrentlyInCreation(String beanName) {
240:                return this .singletonsCurrentlyInCreation.contains(beanName);
241:            }
242:
243:            /**
244:             * Add the given bean to the list of disposable beans in this registry.
245:             * Disposable beans usually correspond to registered singletons,
246:             * matching the bean name but potentially being a different instance
247:             * (for example, a DisposableBean adapter for a singleton that does not
248:             * naturally implement Spring's DisposableBean interface).
249:             * @param beanName the name of the bean
250:             * @param bean the bean instance
251:             */
252:            public void registerDisposableBean(String beanName,
253:                    DisposableBean bean) {
254:                synchronized (this .disposableBeans) {
255:                    this .disposableBeans.put(beanName, bean);
256:                }
257:            }
258:
259:            /**
260:             * Register a dependent bean for the given bean,
261:             * to be destroyed before the given bean is destroyed.
262:             * @param beanName the name of the bean
263:             * @param dependentBeanName the name of the dependent bean
264:             */
265:            public void registerDependentBean(String beanName,
266:                    String dependentBeanName) {
267:                synchronized (this .dependentBeanMap) {
268:                    Set dependencies = (Set) this .dependentBeanMap
269:                            .get(beanName);
270:                    if (dependencies == null) {
271:                        dependencies = CollectionFactory
272:                                .createLinkedSetIfPossible(8);
273:                        this .dependentBeanMap.put(beanName, dependencies);
274:                    }
275:                    dependencies.add(dependentBeanName);
276:                }
277:            }
278:
279:            /**
280:             * Return whether a dependent bean has been registered under the given name.
281:             * @param beanName the name of the bean
282:             */
283:            protected boolean hasDependentBean(String beanName) {
284:                synchronized (this .dependentBeanMap) {
285:                    return this .dependentBeanMap.containsKey(beanName);
286:                }
287:            }
288:
289:            /**
290:             * Return whether a dependent bean has been registered under the given name.
291:             * @param beanName the name of the bean
292:             * @return an unmodifiable Set of dependent bean names (as Strings)
293:             */
294:            protected Set getDependentBeans(String beanName) {
295:                synchronized (this .dependentBeanMap) {
296:                    return Collections
297:                            .unmodifiableSet((Set) this .dependentBeanMap
298:                                    .get(beanName));
299:                }
300:            }
301:
302:            public void destroySingletons() {
303:                if (logger.isInfoEnabled()) {
304:                    logger.info("Destroying singletons in " + this );
305:                }
306:                synchronized (this .singletonObjects) {
307:                    this .singletonsCurrentlyInDestruction = true;
308:                }
309:                synchronized (this .disposableBeans) {
310:                    String[] disposableBeanNames = StringUtils
311:                            .toStringArray(this .disposableBeans.keySet());
312:                    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
313:                        destroySingleton(disposableBeanNames[i]);
314:                    }
315:                }
316:                synchronized (this .singletonObjects) {
317:                    this .singletonObjects.clear();
318:                    this .registeredSingletons.clear();
319:                    this .singletonsCurrentlyInDestruction = false;
320:                }
321:            }
322:
323:            /**
324:             * Destroy the given bean. Delegates to <code>destroyBean</code>
325:             * if a corresponding disposable bean instance is found.
326:             * @param beanName the name of the bean
327:             * @see #destroyBean
328:             */
329:            public void destroySingleton(String beanName) {
330:                synchronized (this .singletonObjects) {
331:                    // Remove a registered singleton of the given name, if any.
332:                    removeSingleton(beanName);
333:                }
334:
335:                // Destroy the corresponding DisposableBean instance.
336:                DisposableBean disposableBean = null;
337:                synchronized (this .disposableBeans) {
338:                    disposableBean = (DisposableBean) this .disposableBeans
339:                            .remove(beanName);
340:                }
341:                destroyBean(beanName, disposableBean);
342:            }
343:
344:            /**
345:             * Destroy the given bean. Must destroy beans that depend on the given
346:             * bean before the bean itself. Should not throw any exceptions.
347:             * @param beanName the name of the bean
348:             * @param bean the bean instance to destroy
349:             */
350:            protected void destroyBean(String beanName, DisposableBean bean) {
351:                Set dependencies = null;
352:                synchronized (this .dependentBeanMap) {
353:                    dependencies = (Set) this .dependentBeanMap.remove(beanName);
354:                }
355:
356:                if (dependencies != null) {
357:                    if (logger.isDebugEnabled()) {
358:                        logger.debug("Retrieved dependent beans for bean '"
359:                                + beanName + "': " + dependencies);
360:                    }
361:                    for (Iterator it = dependencies.iterator(); it.hasNext();) {
362:                        String dependentBeanName = (String) it.next();
363:                        destroySingleton(dependentBeanName);
364:                    }
365:                }
366:
367:                if (bean != null) {
368:                    try {
369:                        bean.destroy();
370:                    } catch (Throwable ex) {
371:                        logger.error("Destroy method on bean with name '"
372:                                + beanName + "' threw an exception", ex);
373:                    }
374:                }
375:            }
376:
377:            /**
378:             * Expose the singleton mutex to subclasses.
379:             * <p>Subclasses should synchronize on the given Object if they perform
380:             * any sort of extended singleton creation phase. In particular, subclasses
381:             * should <i>not</i> have their own mutexes involved in singleton creation,
382:             * to avoid the potential for deadlocks in lazy-init situations.
383:             */
384:            protected final Object getSingletonMutex() {
385:                return this.singletonObjects;
386:            }
387:
388:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.