1 /*
2 * Copyright 2002-2005 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.access;
18
19 import org.springframework.beans.BeansException;
20 import org.springframework.beans.factory.BeanFactory;
21 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
22 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
23 import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
24 import org.springframework.util.Assert;
25
26 /**
27 * One singleton to rule them all. Reads System properties, which
28 * must contain the definition of a bootstrap bean factory using
29 * the Properties syntax supported by PropertiesBeanDefinitionReader.
30 *
31 * <p>The name of the bootstrap factory must be "bootstrapBeanFactory".
32 * Thus a typical definition might be:
33 *
34 * <pre>
35 * bootstrapBeanFactory.class=com.mycompany.MyBeanFactory</pre>
36 *
37 * Use as follows:
38 *
39 * <pre>
40 * BeanFactory bf = BeanFactoryBootstrap.getInstance().getBeanFactory();</pre>
41 *
42 * @author Rod Johnson
43 * @since 02.12.2002
44 * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
45 */
46 public class BeanFactoryBootstrap {
47
48 public static final String BEAN_FACTORY_BEAN_NAME = "bootstrapBeanFactory";
49
50 private static BeanFactoryBootstrap instance;
51
52 private static BeansException startupException;
53
54 private static void initializeSingleton() {
55 try {
56 instance = new BeanFactoryBootstrap();
57 }
58 catch (BeansException ex) {
59 startupException = ex;
60 }
61 }
62
63 // Do initialization when this class is loaded to avoid
64 // potential concurrency issues or the need to synchronize later
65 static {
66 initializeSingleton();
67 }
68
69 /**
70 * Return the singleton instance of the bootstrap factory
71 * @return BeanFactoryBootstrap
72 * @throws org.springframework.beans.BeansException
73 */
74 public static BeanFactoryBootstrap getInstance() throws BeansException {
75 if (startupException != null) {
76 throw startupException;
77 }
78 Assert.notNull(instance);
79 return instance;
80 }
81
82 /**
83 * <b>For testing only. Cleans and reinitalizes the instance.
84 * Do not use in a production application!</b>
85 */
86 protected static void reinitialize() {
87 instance = null;
88 startupException = null;
89 initializeSingleton();
90 }
91
92
93 /** the singleton instance */
94 private BeanFactory bootstrapFactory;
95
96 /**
97 * Apply rules to load factory.
98 */
99 private BeanFactoryBootstrap() throws BeansException {
100 DefaultListableBeanFactory startupFactory = new DefaultListableBeanFactory();
101 PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(startupFactory);
102 try {
103 propReader.registerBeanDefinitions(System.getProperties());
104 this.bootstrapFactory = (BeanFactory) startupFactory.getBean(BEAN_FACTORY_BEAN_NAME, BeanFactory.class);
105 }
106 catch (NoSuchBeanDefinitionException ex) {
107 throw new BootstrapException(
108 "No bean named '" + BEAN_FACTORY_BEAN_NAME + "' in system properties: [" + startupFactory + "]");
109 }
110 catch (BeansException ex) {
111 throw new BootstrapException("Failed to bootstrap bean factory", ex);
112 }
113 }
114
115 /**
116 * Return the BeanFactory managed by the Bootstrap.
117 */
118 public BeanFactory getBeanFactory() {
119 return bootstrapFactory;
120 }
121
122 }