View Javadoc
1   /*
2    * Copyright 2002-2014 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.support;
18  
19  import java.lang.reflect.Constructor;
20  import java.util.Arrays;
21  import java.util.LinkedHashMap;
22  import java.util.LinkedHashSet;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.springframework.beans.BeanMetadataAttributeAccessor;
27  import org.springframework.beans.MutablePropertyValues;
28  import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
29  import org.springframework.beans.factory.config.BeanDefinition;
30  import org.springframework.beans.factory.config.ConstructorArgumentValues;
31  import org.springframework.core.io.DescriptiveResource;
32  import org.springframework.core.io.Resource;
33  import org.springframework.util.Assert;
34  import org.springframework.util.ClassUtils;
35  import org.springframework.util.ObjectUtils;
36  import org.springframework.util.StringUtils;
37  
38  /**
39   * Base class for concrete, full-fledged
40   * {@link org.springframework.beans.factory.config.BeanDefinition} classes,
41   * factoring out common properties of {@link GenericBeanDefinition},
42   * {@link RootBeanDefinition} and {@link ChildBeanDefinition}.
43   *
44   * <p>The autowire constants match the ones defined in the
45   * {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
46   * interface.
47   *
48   * @author Rod Johnson
49   * @author Juergen Hoeller
50   * @author Rob Harrop
51   * @author Mark Fisher
52   * @see RootBeanDefinition
53   * @see ChildBeanDefinition
54   */
55  @SuppressWarnings("serial")
56  public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
57  		implements BeanDefinition, Cloneable {
58  
59  	/**
60  	 * Constant for the default scope name: "", equivalent to singleton status
61  	 * but to be overridden from a parent bean definition (if applicable).
62  	 */
63  	public static final String SCOPE_DEFAULT = "";
64  
65  	/**
66  	 * Constant that indicates no autowiring at all.
67  	 * @see #setAutowireMode
68  	 */
69  	public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
70  
71  	/**
72  	 * Constant that indicates autowiring bean properties by name.
73  	 * @see #setAutowireMode
74  	 */
75  	public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
76  
77  	/**
78  	 * Constant that indicates autowiring bean properties by type.
79  	 * @see #setAutowireMode
80  	 */
81  	public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
82  
83  	/**
84  	 * Constant that indicates autowiring a constructor.
85  	 * @see #setAutowireMode
86  	 */
87  	public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
88  
89  	/**
90  	 * Constant that indicates determining an appropriate autowire strategy
91  	 * through introspection of the bean class.
92  	 * @see #setAutowireMode
93  	 * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
94  	 * use annotation-based autowiring for clearer demarcation of autowiring needs.
95  	 */
96  	@Deprecated
97  	public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
98  
99  	/**
100 	 * Constant that indicates no dependency check at all.
101 	 * @see #setDependencyCheck
102 	 */
103 	public static final int DEPENDENCY_CHECK_NONE = 0;
104 
105 	/**
106 	 * Constant that indicates dependency checking for object references.
107 	 * @see #setDependencyCheck
108 	 */
109 	public static final int DEPENDENCY_CHECK_OBJECTS = 1;
110 
111 	/**
112 	 * Constant that indicates dependency checking for "simple" properties.
113 	 * @see #setDependencyCheck
114 	 * @see org.springframework.beans.BeanUtils#isSimpleProperty
115 	 */
116 	public static final int DEPENDENCY_CHECK_SIMPLE = 2;
117 
118 	/**
119 	 * Constant that indicates dependency checking for all properties
120 	 * (object references as well as "simple" properties).
121 	 * @see #setDependencyCheck
122 	 */
123 	public static final int DEPENDENCY_CHECK_ALL = 3;
124 
125 	/**
126 	 * Constant that indicates the container should attempt to infer the
127 	 * {@link #setDestroyMethodName destroy method name} for a bean as opposed to
128 	 * explicit specification of a method name. The value {@value} is specifically
129 	 * designed to include characters otherwise illegal in a method name, ensuring
130 	 * no possibility of collisions with legitimately named methods having the same
131 	 * name.
132 	 * <p>Currently, the method names detected during destroy method inference
133 	 * are "close" and "shutdown", if present on the specific bean class.
134 	 */
135 	public static final String INFER_METHOD = "(inferred)";
136 
137 
138 	private volatile Object beanClass;
139 
140 	private String scope = SCOPE_DEFAULT;
141 
142 	private boolean abstractFlag = false;
143 
144 	private boolean lazyInit = false;
145 
146 	private int autowireMode = AUTOWIRE_NO;
147 
148 	private int dependencyCheck = DEPENDENCY_CHECK_NONE;
149 
150 	private String[] dependsOn;
151 
152 	private boolean autowireCandidate = true;
153 
154 	private boolean primary = false;
155 
156 	private final Map<String, AutowireCandidateQualifier> qualifiers =
157 			new LinkedHashMap<String, AutowireCandidateQualifier>(0);
158 
159 	private boolean nonPublicAccessAllowed = true;
160 
161 	private boolean lenientConstructorResolution = true;
162 
163 	private ConstructorArgumentValues constructorArgumentValues;
164 
165 	private MutablePropertyValues propertyValues;
166 
167 	private MethodOverrides methodOverrides = new MethodOverrides();
168 
169 	private String factoryBeanName;
170 
171 	private String factoryMethodName;
172 
173 	private String initMethodName;
174 
175 	private String destroyMethodName;
176 
177 	private boolean enforceInitMethod = true;
178 
179 	private boolean enforceDestroyMethod = true;
180 
181 	private boolean synthetic = false;
182 
183 	private int role = BeanDefinition.ROLE_APPLICATION;
184 
185 	private String description;
186 
187 	private Resource resource;
188 
189 
190 	/**
191 	 * Create a new AbstractBeanDefinition with default settings.
192 	 */
193 	protected AbstractBeanDefinition() {
194 		this(null, null);
195 	}
196 
197 	/**
198 	 * Create a new AbstractBeanDefinition with the given
199 	 * constructor argument values and property values.
200 	 */
201 	protected AbstractBeanDefinition(ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
202 		setConstructorArgumentValues(cargs);
203 		setPropertyValues(pvs);
204 	}
205 
206 	/**
207 	 * Create a new AbstractBeanDefinition as a deep copy of the given
208 	 * bean definition.
209 	 * @param original the original bean definition to copy from
210 	 */
211 	protected AbstractBeanDefinition(BeanDefinition original) {
212 		setParentName(original.getParentName());
213 		setBeanClassName(original.getBeanClassName());
214 		setFactoryBeanName(original.getFactoryBeanName());
215 		setFactoryMethodName(original.getFactoryMethodName());
216 		setScope(original.getScope());
217 		setAbstract(original.isAbstract());
218 		setLazyInit(original.isLazyInit());
219 		setRole(original.getRole());
220 		setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
221 		setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
222 		setSource(original.getSource());
223 		copyAttributesFrom(original);
224 
225 		if (original instanceof AbstractBeanDefinition) {
226 			AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
227 			if (originalAbd.hasBeanClass()) {
228 				setBeanClass(originalAbd.getBeanClass());
229 			}
230 			setAutowireMode(originalAbd.getAutowireMode());
231 			setDependencyCheck(originalAbd.getDependencyCheck());
232 			setDependsOn(originalAbd.getDependsOn());
233 			setAutowireCandidate(originalAbd.isAutowireCandidate());
234 			copyQualifiersFrom(originalAbd);
235 			setPrimary(originalAbd.isPrimary());
236 			setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
237 			setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
238 			setInitMethodName(originalAbd.getInitMethodName());
239 			setEnforceInitMethod(originalAbd.isEnforceInitMethod());
240 			setDestroyMethodName(originalAbd.getDestroyMethodName());
241 			setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
242 			setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
243 			setSynthetic(originalAbd.isSynthetic());
244 			setResource(originalAbd.getResource());
245 		}
246 		else {
247 			setResourceDescription(original.getResourceDescription());
248 		}
249 	}
250 
251 
252 	/**
253 	 * Override settings in this bean definition (presumably a copied parent
254 	 * from a parent-child inheritance relationship) from the given bean
255 	 * definition (presumably the child).
256 	 * <ul>
257 	 * <li>Will override beanClass if specified in the given bean definition.
258 	 * <li>Will always take {@code abstract}, {@code scope},
259 	 * {@code lazyInit}, {@code autowireMode}, {@code dependencyCheck},
260 	 * and {@code dependsOn} from the given bean definition.
261 	 * <li>Will add {@code constructorArgumentValues}, {@code propertyValues},
262 	 * {@code methodOverrides} from the given bean definition to existing ones.
263 	 * <li>Will override {@code factoryBeanName}, {@code factoryMethodName},
264 	 * {@code initMethodName}, and {@code destroyMethodName} if specified
265 	 * in the given bean definition.
266 	 * </ul>
267 	 */
268 	public void overrideFrom(BeanDefinition other) {
269 		if (StringUtils.hasLength(other.getBeanClassName())) {
270 			setBeanClassName(other.getBeanClassName());
271 		}
272 		if (StringUtils.hasLength(other.getFactoryBeanName())) {
273 			setFactoryBeanName(other.getFactoryBeanName());
274 		}
275 		if (StringUtils.hasLength(other.getFactoryMethodName())) {
276 			setFactoryMethodName(other.getFactoryMethodName());
277 		}
278 		if (StringUtils.hasLength(other.getScope())) {
279 			setScope(other.getScope());
280 		}
281 		setAbstract(other.isAbstract());
282 		setLazyInit(other.isLazyInit());
283 		setRole(other.getRole());
284 		getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
285 		getPropertyValues().addPropertyValues(other.getPropertyValues());
286 		setSource(other.getSource());
287 		copyAttributesFrom(other);
288 
289 		if (other instanceof AbstractBeanDefinition) {
290 			AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
291 			if (otherAbd.hasBeanClass()) {
292 				setBeanClass(otherAbd.getBeanClass());
293 			}
294 			setAutowireCandidate(otherAbd.isAutowireCandidate());
295 			setAutowireMode(otherAbd.getAutowireMode());
296 			copyQualifiersFrom(otherAbd);
297 			setPrimary(otherAbd.isPrimary());
298 			setDependencyCheck(otherAbd.getDependencyCheck());
299 			setDependsOn(otherAbd.getDependsOn());
300 			setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
301 			setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
302 			if (StringUtils.hasLength(otherAbd.getInitMethodName())) {
303 				setInitMethodName(otherAbd.getInitMethodName());
304 				setEnforceInitMethod(otherAbd.isEnforceInitMethod());
305 			}
306 			if (StringUtils.hasLength(otherAbd.getDestroyMethodName())) {
307 				setDestroyMethodName(otherAbd.getDestroyMethodName());
308 				setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
309 			}
310 			getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
311 			setSynthetic(otherAbd.isSynthetic());
312 			setResource(otherAbd.getResource());
313 		}
314 		else {
315 			setResourceDescription(other.getResourceDescription());
316 		}
317 	}
318 
319 	/**
320 	 * Apply the provided default values to this bean.
321 	 * @param defaults the defaults to apply
322 	 */
323 	public void applyDefaults(BeanDefinitionDefaults defaults) {
324 		setLazyInit(defaults.isLazyInit());
325 		setAutowireMode(defaults.getAutowireMode());
326 		setDependencyCheck(defaults.getDependencyCheck());
327 		setInitMethodName(defaults.getInitMethodName());
328 		setEnforceInitMethod(false);
329 		setDestroyMethodName(defaults.getDestroyMethodName());
330 		setEnforceDestroyMethod(false);
331 	}
332 
333 
334 	/**
335 	 * Return whether this definition specifies a bean class.
336 	 */
337 	public boolean hasBeanClass() {
338 		return (this.beanClass instanceof Class);
339 	}
340 
341 	/**
342 	 * Specify the class for this bean.
343 	 */
344 	public void setBeanClass(Class<?> beanClass) {
345 		this.beanClass = beanClass;
346 	}
347 
348 	/**
349 	 * Return the class of the wrapped bean, if already resolved.
350 	 * @return the bean class, or {@code null} if none defined
351 	 * @throws IllegalStateException if the bean definition does not define a bean class,
352 	 * or a specified bean class name has not been resolved into an actual Class
353 	 */
354 	public Class<?> getBeanClass() throws IllegalStateException {
355 		Object beanClassObject = this.beanClass;
356 		if (beanClassObject == null) {
357 			throw new IllegalStateException("No bean class specified on bean definition");
358 		}
359 		if (!(beanClassObject instanceof Class)) {
360 			throw new IllegalStateException(
361 					"Bean class name [" + beanClassObject + "] has not been resolved into an actual Class");
362 		}
363 		return (Class<?>) beanClassObject;
364 	}
365 
366 	@Override
367 	public void setBeanClassName(String beanClassName) {
368 		this.beanClass = beanClassName;
369 	}
370 
371 	@Override
372 	public String getBeanClassName() {
373 		Object beanClassObject = this.beanClass;
374 		if (beanClassObject instanceof Class) {
375 			return ((Class<?>) beanClassObject).getName();
376 		}
377 		else {
378 			return (String) beanClassObject;
379 		}
380 	}
381 
382 	/**
383 	 * Determine the class of the wrapped bean, resolving it from a
384 	 * specified class name if necessary. Will also reload a specified
385 	 * Class from its name when called with the bean class already resolved.
386 	 * @param classLoader the ClassLoader to use for resolving a (potential) class name
387 	 * @return the resolved bean class
388 	 * @throws ClassNotFoundException if the class name could be resolved
389 	 */
390 	public Class<?> resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException {
391 		String className = getBeanClassName();
392 		if (className == null) {
393 			return null;
394 		}
395 		Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
396 		this.beanClass = resolvedClass;
397 		return resolvedClass;
398 	}
399 
400 
401 	/**
402 	 * Set the name of the target scope for the bean.
403 	 * <p>Default is singleton status, although this is only applied once
404 	 * a bean definition becomes active in the containing factory. A bean
405 	 * definition may eventually inherit its scope from a parent bean definitionFor this
406 	 * reason, the default scope name is empty (empty String), with
407 	 * singleton status being assumed until a resolved scope will be set.
408 	 * @see #SCOPE_SINGLETON
409 	 * @see #SCOPE_PROTOTYPE
410 	 */
411 	@Override
412 	public void setScope(String scope) {
413 		this.scope = scope;
414 	}
415 
416 	/**
417 	 * Return the name of the target scope for the bean.
418 	 */
419 	@Override
420 	public String getScope() {
421 		return this.scope;
422 	}
423 
424 	/**
425 	 * Return whether this a <b>Singleton</b>, with a single shared instance
426 	 * returned from all calls.
427 	 * @see #SCOPE_SINGLETON
428 	 */
429 	@Override
430 	public boolean isSingleton() {
431 		return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
432 	}
433 
434 	/**
435 	 * Return whether this a <b>Prototype</b>, with an independent instance
436 	 * returned for each call.
437 	 * @see #SCOPE_PROTOTYPE
438 	 */
439 	@Override
440 	public boolean isPrototype() {
441 		return SCOPE_PROTOTYPE.equals(scope);
442 	}
443 
444 	/**
445 	 * Set if this bean is "abstract", i.e. not meant to be instantiated itself but
446 	 * rather just serving as parent for concrete child bean definitions.
447 	 * <p>Default is "false". Specify true to tell the bean factory to not try to
448 	 * instantiate that particular bean in any case.
449 	 */
450 	public void setAbstract(boolean abstractFlag) {
451 		this.abstractFlag = abstractFlag;
452 	}
453 
454 	/**
455 	 * Return whether this bean is "abstract", i.e. not meant to be instantiated
456 	 * itself but rather just serving as parent for concrete child bean definitions.
457 	 */
458 	@Override
459 	public boolean isAbstract() {
460 		return this.abstractFlag;
461 	}
462 
463 	/**
464 	 * Set whether this bean should be lazily initialized.
465 	 * <p>If {@code false}, the bean will get instantiated on startup by bean
466 	 * factories that perform eager initialization of singletons.
467 	 */
468 	@Override
469 	public void setLazyInit(boolean lazyInit) {
470 		this.lazyInit = lazyInit;
471 	}
472 
473 	/**
474 	 * Return whether this bean should be lazily initialized, i.e. not
475 	 * eagerly instantiated on startup. Only applicable to a singleton bean.
476 	 */
477 	@Override
478 	public boolean isLazyInit() {
479 		return this.lazyInit;
480 	}
481 
482 
483 	/**
484 	 * Set the autowire mode. This determines whether any automagical detection
485 	 * and setting of bean references will happen. Default is AUTOWIRE_NO,
486 	 * which means there's no autowire.
487 	 * @param autowireMode the autowire mode to set.
488 	 * Must be one of the constants defined in this class.
489 	 * @see #AUTOWIRE_NO
490 	 * @see #AUTOWIRE_BY_NAME
491 	 * @see #AUTOWIRE_BY_TYPE
492 	 * @see #AUTOWIRE_CONSTRUCTOR
493 	 * @see #AUTOWIRE_AUTODETECT
494 	 */
495 	public void setAutowireMode(int autowireMode) {
496 		this.autowireMode = autowireMode;
497 	}
498 
499 	/**
500 	 * Return the autowire mode as specified in the bean definition.
501 	 */
502 	public int getAutowireMode() {
503 		return this.autowireMode;
504 	}
505 
506 	/**
507 	 * Return the resolved autowire code,
508 	 * (resolving AUTOWIRE_AUTODETECT to AUTOWIRE_CONSTRUCTOR or AUTOWIRE_BY_TYPE).
509 	 * @see #AUTOWIRE_AUTODETECT
510 	 * @see #AUTOWIRE_CONSTRUCTOR
511 	 * @see #AUTOWIRE_BY_TYPE
512 	 */
513 	public int getResolvedAutowireMode() {
514 		if (this.autowireMode == AUTOWIRE_AUTODETECT) {
515 			// Work out whether to apply setter autowiring or constructor autowiring.
516 			// If it has a no-arg constructor it's deemed to be setter autowiring,
517 			// otherwise we'll try constructor autowiring.
518 			Constructor<?>[] constructors = getBeanClass().getConstructors();
519 			for (Constructor<?> constructor : constructors) {
520 				if (constructor.getParameterTypes().length == 0) {
521 					return AUTOWIRE_BY_TYPE;
522 				}
523 			}
524 			return AUTOWIRE_CONSTRUCTOR;
525 		}
526 		else {
527 			return this.autowireMode;
528 		}
529 	}
530 
531 	/**
532 	 * Set the dependency check code.
533 	 * @param dependencyCheck the code to set.
534 	 * Must be one of the four constants defined in this class.
535 	 * @see #DEPENDENCY_CHECK_NONE
536 	 * @see #DEPENDENCY_CHECK_OBJECTS
537 	 * @see #DEPENDENCY_CHECK_SIMPLE
538 	 * @see #DEPENDENCY_CHECK_ALL
539 	 */
540 	public void setDependencyCheck(int dependencyCheck) {
541 		this.dependencyCheck = dependencyCheck;
542 	}
543 
544 	/**
545 	 * Return the dependency check code.
546 	 */
547 	public int getDependencyCheck() {
548 		return this.dependencyCheck;
549 	}
550 
551 	/**
552 	 * Set the names of the beans that this bean depends on being initialized.
553 	 * The bean factory will guarantee that these beans get initialized first.
554 	 * <p>Note that dependencies are normally expressed through bean properties or
555 	 * constructor arguments. This property should just be necessary for other kinds
556 	 * of dependencies like statics (*ugh*) or database preparation on startup.
557 	 */
558 	@Override
559 	public void setDependsOn(String... dependsOn) {
560 		this.dependsOn = dependsOn;
561 	}
562 
563 	/**
564 	 * Return the bean names that this bean depends on.
565 	 */
566 	@Override
567 	public String[] getDependsOn() {
568 		return this.dependsOn;
569 	}
570 
571 	/**
572 	 * Set whether this bean is a candidate for getting autowired into some other bean.
573 	 */
574 	@Override
575 	public void setAutowireCandidate(boolean autowireCandidate) {
576 		this.autowireCandidate = autowireCandidate;
577 	}
578 
579 	/**
580 	 * Return whether this bean is a candidate for getting autowired into some other bean.
581 	 */
582 	@Override
583 	public boolean isAutowireCandidate() {
584 		return this.autowireCandidate;
585 	}
586 
587 	/**
588 	 * Set whether this bean is a primary autowire candidate.
589 	 * If this value is true for exactly one bean among multiple
590 	 * matching candidates, it will serve as a tie-breaker.
591 	 */
592 	@Override
593 	public void setPrimary(boolean primary) {
594 		this.primary = primary;
595 	}
596 
597 	/**
598 	 * Return whether this bean is a primary autowire candidate.
599 	 * If this value is true for exactly one bean among multiple
600 	 * matching candidates, it will serve as a tie-breaker.
601 	 */
602 	@Override
603 	public boolean isPrimary() {
604 		return this.primary;
605 	}
606 
607 	/**
608 	 * Register a qualifier to be used for autowire candidate resolution,
609 	 * keyed by the qualifier's type name.
610 	 * @see AutowireCandidateQualifier#getTypeName()
611 	 */
612 	public void addQualifier(AutowireCandidateQualifier qualifier) {
613 		this.qualifiers.put(qualifier.getTypeName(), qualifier);
614 	}
615 
616 	/**
617 	 * Return whether this bean has the specified qualifier.
618 	 */
619 	public boolean hasQualifier(String typeName) {
620 		return this.qualifiers.keySet().contains(typeName);
621 	}
622 
623 	/**
624 	 * Return the qualifier mapped to the provided type name.
625 	 */
626 	public AutowireCandidateQualifier getQualifier(String typeName) {
627 		return this.qualifiers.get(typeName);
628 	}
629 
630 	/**
631 	 * Return all registered qualifiers.
632 	 * @return the Set of {@link AutowireCandidateQualifier} objects.
633 	 */
634 	public Set<AutowireCandidateQualifier> getQualifiers() {
635 		return new LinkedHashSet<AutowireCandidateQualifier>(this.qualifiers.values());
636 	}
637 
638 	/**
639 	 * Copy the qualifiers from the supplied AbstractBeanDefinition to this bean definition.
640 	 * @param source the AbstractBeanDefinition to copy from
641 	 */
642 	public void copyQualifiersFrom(AbstractBeanDefinition source) {
643 		Assert.notNull(source, "Source must not be null");
644 		this.qualifiers.putAll(source.qualifiers);
645 	}
646 
647 
648 	/**
649 	 * Specify whether to allow access to non-public constructors and methods,
650 	 * for the case of externalized metadata pointing to those. The default is
651 	 * {@code true}; switch this to {@code false} for public access only.
652 	 * <p>This applies to constructor resolution, factory method resolution,
653 	 * and also init/destroy methods. Bean property accessors have to be public
654 	 * in any case and are not affected by this setting.
655 	 * <p>Note that annotation-driven configuration will still access non-public
656 	 * members as far as they have been annotated. This setting applies to
657 	 * externalized metadata in this bean definition only.
658 	 */
659 	public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
660 		this.nonPublicAccessAllowed = nonPublicAccessAllowed;
661 	}
662 
663 	/**
664 	 * Return whether to allow access to non-public constructors and methods.
665 	 */
666 	public boolean isNonPublicAccessAllowed() {
667 		return this.nonPublicAccessAllowed;
668 	}
669 
670 	/**
671 	 * Specify whether to resolve constructors in lenient mode ({@code true},
672 	 * which is the default) or to switch to strict resolution (throwing an exception
673 	 * in case of ambiguous constructors that all match when converting the arguments,
674 	 * whereas lenient mode would use the one with the 'closest' type matches).
675 	 */
676 	public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
677 		this.lenientConstructorResolution = lenientConstructorResolution;
678 	}
679 
680 	/**
681 	 * Return whether to resolve constructors in lenient mode or in strict mode.
682 	 */
683 	public boolean isLenientConstructorResolution() {
684 		return this.lenientConstructorResolution;
685 	}
686 
687 	/**
688 	 * Specify constructor argument values for this bean.
689 	 */
690 	public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
691 		this.constructorArgumentValues =
692 				(constructorArgumentValues != null ? constructorArgumentValues : new ConstructorArgumentValues());
693 	}
694 
695 	/**
696 	 * Return constructor argument values for this bean (never {@code null}).
697 	 */
698 	@Override
699 	public ConstructorArgumentValues getConstructorArgumentValues() {
700 		return this.constructorArgumentValues;
701 	}
702 
703 	/**
704 	 * Return if there are constructor argument values defined for this bean.
705 	 */
706 	public boolean hasConstructorArgumentValues() {
707 		return !this.constructorArgumentValues.isEmpty();
708 	}
709 
710 	/**
711 	 * Specify property values for this bean, if any.
712 	 */
713 	public void setPropertyValues(MutablePropertyValues propertyValues) {
714 		this.propertyValues = (propertyValues != null ? propertyValues : new MutablePropertyValues());
715 	}
716 
717 	/**
718 	 * Return property values for this bean (never {@code null}).
719 	 */
720 	@Override
721 	public MutablePropertyValues getPropertyValues() {
722 		return this.propertyValues;
723 	}
724 
725 	/**
726 	 * Specify method overrides for the bean, if any.
727 	 */
728 	public void setMethodOverrides(MethodOverrides methodOverrides) {
729 		this.methodOverrides = (methodOverrides != null ? methodOverrides : new MethodOverrides());
730 	}
731 
732 	/**
733 	 * Return information about methods to be overridden by the IoC
734 	 * container. This will be empty if there are no method overrides.
735 	 * Never returns null.
736 	 */
737 	public MethodOverrides getMethodOverrides() {
738 		return this.methodOverrides;
739 	}
740 
741 
742 	@Override
743 	public void setFactoryBeanName(String factoryBeanName) {
744 		this.factoryBeanName = factoryBeanName;
745 	}
746 
747 	@Override
748 	public String getFactoryBeanName() {
749 		return this.factoryBeanName;
750 	}
751 
752 	@Override
753 	public void setFactoryMethodName(String factoryMethodName) {
754 		this.factoryMethodName = factoryMethodName;
755 	}
756 
757 	@Override
758 	public String getFactoryMethodName() {
759 		return this.factoryMethodName;
760 	}
761 
762 	/**
763 	 * Set the name of the initializer method. The default is {@code null}
764 	 * in which case there is no initializer method.
765 	 */
766 	public void setInitMethodName(String initMethodName) {
767 		this.initMethodName = initMethodName;
768 	}
769 
770 	/**
771 	 * Return the name of the initializer method.
772 	 */
773 	public String getInitMethodName() {
774 		return this.initMethodName;
775 	}
776 
777 	/**
778 	 * Specify whether or not the configured init method is the default.
779 	 * Default value is {@code false}.
780 	 * @see #setInitMethodName
781 	 */
782 	public void setEnforceInitMethod(boolean enforceInitMethod) {
783 		this.enforceInitMethod = enforceInitMethod;
784 	}
785 
786 	/**
787 	 * Indicate whether the configured init method is the default.
788 	 * @see #getInitMethodName()
789 	 */
790 	public boolean isEnforceInitMethod() {
791 		return this.enforceInitMethod;
792 	}
793 
794 	/**
795 	 * Set the name of the destroy method. The default is {@code null}
796 	 * in which case there is no destroy method.
797 	 */
798 	public void setDestroyMethodName(String destroyMethodName) {
799 		this.destroyMethodName = destroyMethodName;
800 	}
801 
802 	/**
803 	 * Return the name of the destroy method.
804 	 */
805 	public String getDestroyMethodName() {
806 		return this.destroyMethodName;
807 	}
808 
809 	/**
810 	 * Specify whether or not the configured destroy method is the default.
811 	 * Default value is {@code false}.
812 	 * @see #setDestroyMethodName
813 	 */
814 	public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
815 		this.enforceDestroyMethod = enforceDestroyMethod;
816 	}
817 
818 	/**
819 	 * Indicate whether the configured destroy method is the default.
820 	 * @see #getDestroyMethodName
821 	 */
822 	public boolean isEnforceDestroyMethod() {
823 		return this.enforceDestroyMethod;
824 	}
825 
826 
827 	/**
828 	 * Set whether this bean definition is 'synthetic', that is, not defined
829 	 * by the application itself (for example, an infrastructure bean such
830 	 * as a helper for auto-proxying, created through {@code &ltaop:config&gt;}).
831 	 */
832 	public void setSynthetic(boolean synthetic) {
833 		this.synthetic = synthetic;
834 	}
835 
836 	/**
837 	 * Return whether this bean definition is 'synthetic', that is,
838 	 * not defined by the application itself.
839 	 */
840 	public boolean isSynthetic() {
841 		return this.synthetic;
842 	}
843 
844 	/**
845 	 * Set the role hint for this {@code BeanDefinition}.
846 	 */
847 	public void setRole(int role) {
848 		this.role = role;
849 	}
850 
851 	/**
852 	 * Return the role hint for this {@code BeanDefinition}.
853 	 */
854 	@Override
855 	public int getRole() {
856 		return this.role;
857 	}
858 
859 
860 	/**
861 	 * Set a human-readable description of this bean definition.
862 	 */
863 	public void setDescription(String description) {
864 		this.description = description;
865 	}
866 
867 	@Override
868 	public String getDescription() {
869 		return this.description;
870 	}
871 
872 	/**
873 	 * Set the resource that this bean definition came from
874 	 * (for the purpose of showing context in case of errors).
875 	 */
876 	public void setResource(Resource resource) {
877 		this.resource = resource;
878 	}
879 
880 	/**
881 	 * Return the resource that this bean definition came from.
882 	 */
883 	public Resource getResource() {
884 		return this.resource;
885 	}
886 
887 	/**
888 	 * Set a description of the resource that this bean definition
889 	 * came from (for the purpose of showing context in case of errors).
890 	 */
891 	public void setResourceDescription(String resourceDescription) {
892 		this.resource = new DescriptiveResource(resourceDescription);
893 	}
894 
895 	@Override
896 	public String getResourceDescription() {
897 		return (this.resource != null ? this.resource.getDescription() : null);
898 	}
899 
900 	/**
901 	 * Set the originating (e.g. decorated) BeanDefinition, if any.
902 	 */
903 	public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
904 		this.resource = new BeanDefinitionResource(originatingBd);
905 	}
906 
907 	@Override
908 	public BeanDefinition getOriginatingBeanDefinition() {
909 		return (this.resource instanceof BeanDefinitionResource ?
910 				((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
911 	}
912 
913 	/**
914 	 * Validate this bean definition.
915 	 * @throws BeanDefinitionValidationException in case of validation failure
916 	 */
917 	public void validate() throws BeanDefinitionValidationException {
918 		if (!getMethodOverrides().isEmpty() && getFactoryMethodName() != null) {
919 			throw new BeanDefinitionValidationException(
920 					"Cannot combine static factory method with method overrides: " +
921 					"the static factory method must create the instance");
922 		}
923 
924 		if (hasBeanClass()) {
925 			prepareMethodOverrides();
926 		}
927 	}
928 
929 	/**
930 	 * Validate and prepare the method overrides defined for this bean.
931 	 * Checks for existence of a method with the specified name.
932 	 * @throws BeanDefinitionValidationException in case of validation failure
933 	 */
934 	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
935 		// Check that lookup methods exists.
936 		MethodOverrides methodOverrides = getMethodOverrides();
937 		if (!methodOverrides.isEmpty()) {
938 			for (MethodOverride mo : methodOverrides.getOverrides()) {
939 				prepareMethodOverride(mo);
940 			}
941 		}
942 	}
943 
944 	/**
945 	 * Validate and prepare the given method override.
946 	 * Checks for existence of a method with the specified name,
947 	 * marking it as not overloaded if none found.
948 	 * @param mo the MethodOverride object to validate
949 	 * @throws BeanDefinitionValidationException in case of validation failure
950 	 */
951 	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
952 		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
953 		if (count == 0) {
954 			throw new BeanDefinitionValidationException(
955 					"Invalid method override: no method with name '" + mo.getMethodName() +
956 					"' on class [" + getBeanClassName() + "]");
957 		}
958 		else if (count == 1) {
959 			// Mark override as not overloaded, to avoid the overhead of arg type checking.
960 			mo.setOverloaded(false);
961 		}
962 	}
963 
964 
965 	/**
966 	 * Public declaration of Object's {@code clone()} method.
967 	 * Delegates to {@link #cloneBeanDefinition()}.
968 	 * @see Object#clone()
969 	 */
970 	@Override
971 	public Object clone() {
972 		return cloneBeanDefinition();
973 	}
974 
975 	/**
976 	 * Clone this bean definition.
977 	 * To be implemented by concrete subclasses.
978 	 * @return the cloned bean definition object
979 	 */
980 	public abstract AbstractBeanDefinition cloneBeanDefinition();
981 
982 
983 	@Override
984 	public boolean equals(Object other) {
985 		if (this == other) {
986 			return true;
987 		}
988 		if (!(other instanceof AbstractBeanDefinition)) {
989 			return false;
990 		}
991 
992 		AbstractBeanDefinition that = (AbstractBeanDefinition) other;
993 
994 		if (!ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName())) return false;
995 		if (!ObjectUtils.nullSafeEquals(this.scope, that.scope)) return false;
996 		if (this.abstractFlag != that.abstractFlag) return false;
997 		if (this.lazyInit != that.lazyInit) return false;
998 
999 		if (this.autowireMode != that.autowireMode) return false;
1000 		if (this.dependencyCheck != that.dependencyCheck) return false;
1001 		if (!Arrays.equals(this.dependsOn, that.dependsOn)) return false;
1002 		if (this.autowireCandidate != that.autowireCandidate) return false;
1003 		if (!ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers)) return false;
1004 		if (this.primary != that.primary) return false;
1005 
1006 		if (this.nonPublicAccessAllowed != that.nonPublicAccessAllowed) return false;
1007 		if (this.lenientConstructorResolution != that.lenientConstructorResolution) return false;
1008 		if (!ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues)) return false;
1009 		if (!ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues)) return false;
1010 		if (!ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides)) return false;
1011 
1012 		if (!ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName)) return false;
1013 		if (!ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName)) return false;
1014 		if (!ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName)) return false;
1015 		if (this.enforceInitMethod != that.enforceInitMethod) return false;
1016 		if (!ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName)) return false;
1017 		if (this.enforceDestroyMethod != that.enforceDestroyMethod) return false;
1018 
1019 		if (this.synthetic != that.synthetic) return false;
1020 		if (this.role != that.role) return false;
1021 
1022 		return super.equals(other);
1023 	}
1024 
1025 	@Override
1026 	public int hashCode() {
1027 		int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
1028 		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
1029 		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
1030 		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
1031 		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
1032 		hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
1033 		hashCode = 29 * hashCode + super.hashCode();
1034 		return hashCode;
1035 	}
1036 
1037 	@Override
1038 	public String toString() {
1039 		StringBuilder sb = new StringBuilder("class [");
1040 		sb.append(getBeanClassName()).append("]");
1041 		sb.append("; scope=").append(this.scope);
1042 		sb.append("; abstract=").append(this.abstractFlag);
1043 		sb.append("; lazyInit=").append(this.lazyInit);
1044 		sb.append("; autowireMode=").append(this.autowireMode);
1045 		sb.append("; dependencyCheck=").append(this.dependencyCheck);
1046 		sb.append("; autowireCandidate=").append(this.autowireCandidate);
1047 		sb.append("; primary=").append(this.primary);
1048 		sb.append("; factoryBeanName=").append(this.factoryBeanName);
1049 		sb.append("; factoryMethodName=").append(this.factoryMethodName);
1050 		sb.append("; initMethodName=").append(this.initMethodName);
1051 		sb.append("; destroyMethodName=").append(this.destroyMethodName);
1052 		if (this.resource != null) {
1053 			sb.append("; defined in ").append(this.resource.getDescription());
1054 		}
1055 		return sb.toString();
1056 	}
1057 
1058 }