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.HashSet;
021: import java.util.Set;
022:
023: import org.springframework.beans.MutablePropertyValues;
024: import org.springframework.beans.factory.config.BeanDefinition;
025: import org.springframework.beans.factory.config.ConstructorArgumentValues;
026:
027: /**
028: * A root bean definition represents the merged bean definition that backs
029: * a specific bean in a Spring BeanFactory at runtime. It might have been created
030: * from multiple original bean definitions that inherit from each other,
031: * typically registered as {@link GenericBeanDefinition GenericBeanDefinitions}.
032: * A root bean definition is essentially the 'unified' bean definition view at runtime.
033: *
034: * <p>Root bean definitions may also be used for registering individual bean definitions
035: * in the configuration phase. However, since Spring 2.5, the preferred way to register
036: * bean definitions programmatically is the {@link GenericBeanDefinition} class.
037: * GenericBeanDefinition has the advantage that it allows to dynamically define
038: * parent dependencies, not 'hard-coding' the role as a root bean definition.
039: *
040: * @author Rod Johnson
041: * @author Juergen Hoeller
042: * @see GenericBeanDefinition
043: * @see ChildBeanDefinition
044: */
045: public class RootBeanDefinition extends AbstractBeanDefinition {
046:
047: private final Set externallyManagedInitMethods = Collections
048: .synchronizedSet(new HashSet());
049:
050: private final Set externallyManagedDestroyMethods = Collections
051: .synchronizedSet(new HashSet());
052:
053: /** Package-visible field for caching the resolved constructor or factory method */
054: volatile Object resolvedConstructorOrFactoryMethod;
055:
056: /** Package-visible field for caching fully resolved constructor arguments */
057: volatile Object[] resolvedConstructorArguments;
058:
059: /** Package-visible field for caching partly prepared constructor arguments */
060: volatile Object[] preparedConstructorArguments;
061:
062: /** Package-visible field that marks the constructor arguments as resolved */
063: volatile boolean constructorArgumentsResolved = false;
064:
065: /** Package-visible field that indicates a before-instantiation post-processor having kicked in */
066: volatile Boolean beforeInstantiationResolved;
067:
068: /** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied */
069: volatile boolean postProcessed = false;
070:
071: /**
072: * Create a new RootBeanDefinition, to be configured through its bean
073: * properties and configuration methods.
074: * @see #setBeanClass
075: * @see #setBeanClassName
076: * @see #setSingleton
077: * @see #setAutowireMode
078: * @see #setDependencyCheck
079: * @see #setConstructorArgumentValues
080: * @see #setPropertyValues
081: */
082: public RootBeanDefinition() {
083: super ();
084: }
085:
086: /**
087: * Create a new RootBeanDefinition for a singleton.
088: * @param beanClass the class of the bean to instantiate
089: */
090: public RootBeanDefinition(Class beanClass) {
091: super ();
092: setBeanClass(beanClass);
093: }
094:
095: /**
096: * Create a new RootBeanDefinition with the given singleton status.
097: * @param beanClass the class of the bean to instantiate
098: * @param singleton the singleton status of the bean
099: */
100: public RootBeanDefinition(Class beanClass, boolean singleton) {
101: super ();
102: setBeanClass(beanClass);
103: setSingleton(singleton);
104: }
105:
106: /**
107: * Create a new RootBeanDefinition for a singleton,
108: * using the given autowire mode.
109: * @param beanClass the class of the bean to instantiate
110: * @param autowireMode by name or type, using the constants in this interface
111: */
112: public RootBeanDefinition(Class beanClass, int autowireMode) {
113: super ();
114: setBeanClass(beanClass);
115: setAutowireMode(autowireMode);
116: }
117:
118: /**
119: * Create a new RootBeanDefinition for a singleton,
120: * using the given autowire mode.
121: * @param beanClass the class of the bean to instantiate
122: * @param autowireMode by name or type, using the constants in this interface
123: * @param dependencyCheck whether to perform a dependency check for objects
124: * (not applicable to autowiring a constructor, thus ignored there)
125: */
126: public RootBeanDefinition(Class beanClass, int autowireMode,
127: boolean dependencyCheck) {
128: super ();
129: setBeanClass(beanClass);
130: setAutowireMode(autowireMode);
131: if (dependencyCheck
132: && getResolvedAutowireMode() != AUTOWIRE_CONSTRUCTOR) {
133: setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
134: }
135: }
136:
137: /**
138: * Create a new RootBeanDefinition for a singleton,
139: * providing property values.
140: * @param beanClass the class of the bean to instantiate
141: * @param pvs the property values to apply
142: */
143: public RootBeanDefinition(Class beanClass, MutablePropertyValues pvs) {
144: super (null, pvs);
145: setBeanClass(beanClass);
146: }
147:
148: /**
149: * Create a new RootBeanDefinition with the given singleton status,
150: * providing property values.
151: * @param beanClass the class of the bean to instantiate
152: * @param pvs the property values to apply
153: * @param singleton the singleton status of the bean
154: */
155: public RootBeanDefinition(Class beanClass,
156: MutablePropertyValues pvs, boolean singleton) {
157: super (null, pvs);
158: setBeanClass(beanClass);
159: setSingleton(singleton);
160: }
161:
162: /**
163: * Create a new RootBeanDefinition for a singleton,
164: * providing constructor arguments and property values.
165: * @param beanClass the class of the bean to instantiate
166: * @param cargs the constructor argument values to apply
167: * @param pvs the property values to apply
168: */
169: public RootBeanDefinition(Class beanClass,
170: ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
171: super (cargs, pvs);
172: setBeanClass(beanClass);
173: }
174:
175: /**
176: * Create a new RootBeanDefinition for a singleton,
177: * providing constructor arguments and property values.
178: * <p>Takes a bean class name to avoid eager loading of the bean class.
179: * @param beanClassName the name of the class to instantiate
180: * @param cargs the constructor argument values to apply
181: * @param pvs the property values to apply
182: */
183: public RootBeanDefinition(String beanClassName,
184: ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
185: super (cargs, pvs);
186: setBeanClassName(beanClassName);
187: }
188:
189: /**
190: * Create a new RootBeanDefinition as deep copy of the given
191: * bean definition.
192: * @param original the original bean definition to copy from
193: */
194: public RootBeanDefinition(RootBeanDefinition original) {
195: super ((BeanDefinition) original);
196: }
197:
198: /**
199: * Create a new RootBeanDefinition as deep copy of the given
200: * bean definition.
201: * @param original the original bean definition to copy from
202: */
203: RootBeanDefinition(BeanDefinition original) {
204: super (original);
205: }
206:
207: public String getParentName() {
208: return null;
209: }
210:
211: public void setParentName(String parentName) {
212: if (parentName != null) {
213: throw new IllegalArgumentException(
214: "Root bean cannot be changed into a child bean with parent reference");
215: }
216: }
217:
218: public void registerExternallyManagedInitMethod(String initMethod) {
219: this .externallyManagedInitMethods.add(initMethod);
220: }
221:
222: public boolean isExternallyManagedInitMethod(String initMethod) {
223: return this .externallyManagedInitMethods.contains(initMethod);
224: }
225:
226: public void registerExternallyManagedDestroyMethod(
227: String destroyMethod) {
228: this .externallyManagedDestroyMethods.add(destroyMethod);
229: }
230:
231: public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
232: return this .externallyManagedDestroyMethods
233: .contains(destroyMethod);
234: }
235:
236: public AbstractBeanDefinition cloneBeanDefinition() {
237: return new RootBeanDefinition(this );
238: }
239:
240: public boolean equals(Object other) {
241: return (this == other || (other instanceof RootBeanDefinition && super
242: .equals(other)));
243: }
244:
245: public String toString() {
246: return "Root bean: " + super.toString();
247: }
248:
249: }
|