1. /*
  2. * Copyright 2002-2004 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. package org.springframework.context.access;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19. import org.springframework.beans.BeansException;
  20. import org.springframework.beans.factory.BeanFactory;
  21. import org.springframework.beans.factory.access.BeanFactoryLocator;
  22. import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
  23. import org.springframework.context.ConfigurableApplicationContext;
  24. import org.springframework.context.support.FileSystemXmlApplicationContext;
  25. /**
  26. * <p>Variant of SingletonBeanFactoryLocator which creates its internal bean
  27. * factory reference definition as an ApplicationContext instead of
  28. * SingletonBeanFactoryLocator's BeanFactory. For almost all usage scenarios, this
  29. * will not make a difference, since withing that ApplicationContext or BeanFactory
  30. * you are still free to create either BeanFactories or ApplicationContexts. The
  31. * main reason one would need to use this class is if BeanPostProcessing (or other
  32. * ApplicationContext specific features are needed in the bean reference definition
  33. * itself.</p>
  34. *
  35. * <p><strong>Note: </strong>This class uses <strong>beanRefContext.xml</strong>
  36. * as the default name for the bean factory reference definition. It is not possible
  37. * nor legal to share definitions with SingletonBeanFactoryLocator at the same time.
  38. *
  39. * @author Colin Sampaleanu
  40. * @version $Revision: 1.4 $
  41. * @see org.springframework.context.access.DefaultLocatorFactory
  42. * @version $Id: ContextSingletonBeanFactoryLocator.java,v 1.4 2004/03/18 02:46:13 trisberg Exp $
  43. */
  44. public class ContextSingletonBeanFactoryLocator extends SingletonBeanFactoryLocator {
  45. public static final String BEANS_REFS_XML_NAME = "beanRefContext.xml";
  46. // the keyed singleton instances
  47. private static Map instances = new HashMap();
  48. /**
  49. * Returns an instance which uses the default "beanRefContext.xml", as the name
  50. * of the definition file(s). All resources returned by the current thread's context
  51. * classloader's getResources() method with this name will be combined to create a
  52. * definition, which is just a BeanFactory.
  53. */
  54. public static BeanFactoryLocator getInstance() throws BeansException {
  55. return getInstance(BEANS_REFS_XML_NAME);
  56. }
  57. /**
  58. * Returns an instance which uses the the specified selector, as the name of the
  59. * definition file(s). All resources returned by the current thread's context
  60. * classloader's getResources() method with this name will be combined to create a
  61. * definition, which is just a a BeanFactory.
  62. * @param selector the name of the resource(s) which will be read and combine to
  63. * form the definition for the SingletonBeanFactoryLocator instance
  64. */
  65. public static BeanFactoryLocator getInstance(String selector) throws BeansException {
  66. synchronized (instances) {
  67. if (logger.isDebugEnabled()) {
  68. logger.debug("ContextSingletonBeanFactoryLocator.getInstance(): instances.hashCode=" +
  69. instances.hashCode() + ", instances=" + instances);
  70. }
  71. BeanFactoryLocator bfl = (BeanFactoryLocator) instances.get(selector);
  72. if (bfl == null) {
  73. bfl = new ContextSingletonBeanFactoryLocator(selector);
  74. instances.put(selector, bfl);
  75. }
  76. return bfl;
  77. }
  78. }
  79. /**
  80. * Constructor which uses the default "bean-refs.xml", as the name of the
  81. * definition file(s). All resources returned by the definition classloader's
  82. * getResources() method with this name will be combined to create a definition.
  83. */
  84. protected ContextSingletonBeanFactoryLocator() {
  85. super(BEANS_REFS_XML_NAME);
  86. }
  87. /**
  88. * Constructor which uses the the specified name as the name of the
  89. * definition file(s). All resources returned by the definition classloader's
  90. * getResources() method with this name will be combined to create a definition.
  91. */
  92. protected ContextSingletonBeanFactoryLocator(String resourceName) {
  93. super(resourceName);
  94. }
  95. /**
  96. * Overrides default method to create definition object as an ApplicationContext
  97. * instead of the default BeanFactory. This does not affect what can actually
  98. * be loaded by that definition.
  99. */
  100. protected BeanFactory createDefinition(String[] resources) throws BeansException {
  101. return new FileSystemXmlApplicationContext(resources);
  102. }
  103. /**
  104. * Overrides default method to work with ApplicationContext
  105. */
  106. protected void destroyDefinition(BeanFactory groupDef, String resourceName) throws BeansException {
  107. if (groupDef instanceof ConfigurableApplicationContext) {
  108. // debugging trace only
  109. if (logger.isDebugEnabled()) {
  110. logger.debug("ContextSingletonBeanFactoryLocator group with resourceName '"
  111. + resourceName
  112. + "' being released, as no more references.");
  113. }
  114. ((ConfigurableApplicationContext) groupDef).close();
  115. }
  116. }
  117. }