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.lang.reflect.Constructor;
020: import java.util.Arrays;
021: import java.util.Iterator;
022:
023: import org.springframework.beans.MutablePropertyValues;
024: import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
025: import org.springframework.beans.factory.config.BeanDefinition;
026: import org.springframework.beans.factory.config.ConstructorArgumentValues;
027: import org.springframework.core.AttributeAccessorSupport;
028: import org.springframework.util.Assert;
029: import org.springframework.util.ClassUtils;
030: import org.springframework.util.ObjectUtils;
031:
032: /**
033: * Base class for concrete, full-fledged
034: * {@link org.springframework.beans.factory.config.BeanDefinition} classes,
035: * factoring out common properties of {@link RootBeanDefinition} and
036: * {@link ChildBeanDefinition}.
037: *
038: * <p>The autowire constants match the ones defined in the
039: * {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
040: * interface.
041: *
042: * @author Rod Johnson
043: * @author Juergen Hoeller
044: * @author Rob Harrop
045: * @see RootBeanDefinition
046: * @see ChildBeanDefinition
047: */
048: public abstract class AbstractBeanDefinition extends
049: AttributeAccessorSupport implements BeanDefinition {
050:
051: /**
052: * Constant that indicates no autowiring at all.
053: * @see #setAutowireMode
054: */
055: public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
056:
057: /**
058: * Constant that indicates autowiring bean properties by name.
059: * @see #setAutowireMode
060: */
061: public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
062:
063: /**
064: * Constant that indicates autowiring bean properties by type.
065: * @see #setAutowireMode
066: */
067: public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
068:
069: /**
070: * Constant that indicates autowiring a constructor.
071: * @see #setAutowireMode
072: */
073: public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
074:
075: /**
076: * Constant that indicates determining an appropriate autowire strategy
077: * through introspection of the bean class.
078: * @see #setAutowireMode
079: */
080: public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
081:
082: /**
083: * Constant that indicates no dependency check at all.
084: * @see #setDependencyCheck
085: */
086: public static final int DEPENDENCY_CHECK_NONE = 0;
087:
088: /**
089: * Constant that indicates dependency checking for object references.
090: * @see #setDependencyCheck
091: */
092: public static final int DEPENDENCY_CHECK_OBJECTS = 1;
093:
094: /**
095: * Constant that indicates dependency checking for "simple" properties.
096: * @see #setDependencyCheck
097: * @see org.springframework.beans.BeanUtils#isSimpleProperty
098: */
099: public static final int DEPENDENCY_CHECK_SIMPLE = 2;
100:
101: /**
102: * Constant that indicates dependency checking for all properties
103: * (object references as well as "simple" properties).
104: * @see #setDependencyCheck
105: */
106: public static final int DEPENDENCY_CHECK_ALL = 3;
107:
108: private Object beanClass;
109:
110: private String scope = SCOPE_SINGLETON;
111:
112: private boolean singleton = true;
113:
114: private boolean prototype = false;
115:
116: private boolean abstractFlag = false;
117:
118: private boolean lazyInit = false;
119:
120: private boolean autowireCandidate = true;
121:
122: private int autowireMode = AUTOWIRE_NO;
123:
124: private int dependencyCheck = DEPENDENCY_CHECK_NONE;
125:
126: private String[] dependsOn;
127:
128: private ConstructorArgumentValues constructorArgumentValues;
129:
130: private MutablePropertyValues propertyValues;
131:
132: private MethodOverrides methodOverrides = new MethodOverrides();
133:
134: private String factoryBeanName;
135:
136: private String factoryMethodName;
137:
138: private String initMethodName;
139:
140: private String destroyMethodName;
141:
142: private boolean enforceInitMethod = true;
143:
144: private boolean enforceDestroyMethod = true;
145:
146: private boolean synthetic = false;
147:
148: private String resourceDescription;
149:
150: private Object source;
151:
152: private int role = BeanDefinition.ROLE_APPLICATION;
153:
154: /**
155: * Create a new AbstractBeanDefinition with default settings.
156: */
157: protected AbstractBeanDefinition() {
158: this (null, null);
159: }
160:
161: /**
162: * Create a new AbstractBeanDefinition with the given
163: * constructor argument values and property values.
164: */
165: protected AbstractBeanDefinition(ConstructorArgumentValues cargs,
166: MutablePropertyValues pvs) {
167: setConstructorArgumentValues(cargs);
168: setPropertyValues(pvs);
169: }
170:
171: /**
172: * Create a new AbstractBeanDefinition as deep copy of the given
173: * bean definition.
174: * @param original the original bean definition to copy from
175: */
176: protected AbstractBeanDefinition(AbstractBeanDefinition original) {
177: this .beanClass = original.beanClass;
178:
179: setScope(original.getScope());
180: setAbstract(original.isAbstract());
181: setLazyInit(original.isLazyInit());
182:
183: setAutowireCandidate(original.isAutowireCandidate());
184: setAutowireMode(original.getAutowireMode());
185: setDependencyCheck(original.getDependencyCheck());
186: setDependsOn(original.getDependsOn());
187:
188: setConstructorArgumentValues(new ConstructorArgumentValues(
189: original.getConstructorArgumentValues()));
190: setPropertyValues(new MutablePropertyValues(original
191: .getPropertyValues()));
192: setMethodOverrides(new MethodOverrides(original
193: .getMethodOverrides()));
194:
195: setFactoryBeanName(original.getFactoryBeanName());
196: setFactoryMethodName(original.getFactoryMethodName());
197: setInitMethodName(original.getInitMethodName());
198: setEnforceInitMethod(original.isEnforceInitMethod());
199: setDestroyMethodName(original.getDestroyMethodName());
200: setEnforceDestroyMethod(original.isEnforceDestroyMethod());
201:
202: setSynthetic(original.isSynthetic());
203: setResourceDescription(original.getResourceDescription());
204: setSource(original.getSource());
205: setRole(original.getRole());
206:
207: copyAttributesFrom(original);
208: }
209:
210: /**
211: * Override settings in this bean definition (assumably a copied parent
212: * from a parent-child inheritance relationship) from the given bean
213: * definition (assumably the child).
214: * <ul>
215: * <li>Will override beanClass if specified in the given bean definition.
216: * <li>Will always take <code>abstract</code>, <code>scope</code>,
217: * <code>lazyInit</code>, <code>autowireMode</code>, <code>dependencyCheck</code>,
218: * and <code>dependsOn</code> from the given bean definition.
219: * <li>Will add <code>constructorArgumentValues</code>, <code>propertyValues</code>,
220: * <code>methodOverrides</code> from the given bean definition to existing ones.
221: * <li>Will override <code>factoryBeanName</code>, <code>factoryMethodName</code>,
222: * <code>initMethodName</code>, and <code>destroyMethodName</code> if specified
223: * in the given bean definition.
224: * </ul>
225: */
226: public void overrideFrom(AbstractBeanDefinition other) {
227: if (other.beanClass != null) {
228: this .beanClass = other.beanClass;
229: }
230:
231: setScope(other.getScope());
232: setAbstract(other.isAbstract());
233: setLazyInit(other.isLazyInit());
234:
235: setAutowireCandidate(other.isAutowireCandidate());
236: setAutowireMode(other.getAutowireMode());
237: setDependencyCheck(other.getDependencyCheck());
238: setDependsOn(other.getDependsOn());
239:
240: getConstructorArgumentValues().addArgumentValues(
241: other.getConstructorArgumentValues());
242: getPropertyValues()
243: .addPropertyValues(other.getPropertyValues());
244: getMethodOverrides().addOverrides(other.getMethodOverrides());
245:
246: if (other.getFactoryBeanName() != null) {
247: setFactoryBeanName(other.getFactoryBeanName());
248: }
249: if (other.getFactoryMethodName() != null) {
250: setFactoryMethodName(other.getFactoryMethodName());
251: }
252: if (other.getInitMethodName() != null) {
253: setInitMethodName(other.getInitMethodName());
254: setEnforceInitMethod(other.isEnforceInitMethod());
255: }
256: if (other.getDestroyMethodName() != null) {
257: setDestroyMethodName(other.getDestroyMethodName());
258: setEnforceDestroyMethod(other.isEnforceDestroyMethod());
259: }
260:
261: setSynthetic(other.isSynthetic());
262: setResourceDescription(other.getResourceDescription());
263: setSource(other.getSource());
264: setRole(other.getRole());
265:
266: copyAttributesFrom(other);
267: }
268:
269: /**
270: * Return whether this definition specifies a bean class.
271: */
272: public boolean hasBeanClass() {
273: return (this .beanClass instanceof Class);
274: }
275:
276: /**
277: * Specify the class for this bean.
278: */
279: public void setBeanClass(Class beanClass) {
280: this .beanClass = beanClass;
281: }
282:
283: /**
284: * Return the class of the wrapped bean.
285: * @throws IllegalStateException if the bean definition does not define a bean class,
286: * or a specified bean class name has not been resolved into an actual Class
287: */
288: public Class getBeanClass() throws IllegalStateException {
289: if (this .beanClass == null) {
290: throw new IllegalStateException(
291: "No bean class specified on bean definition");
292: }
293: if (!(this .beanClass instanceof Class)) {
294: throw new IllegalStateException("Bean class name ["
295: + this .beanClass
296: + "] has not been resolved into an actual Class");
297: }
298: return (Class) this .beanClass;
299: }
300:
301: /**
302: * Specify the class name for this bean.
303: */
304: public void setBeanClassName(String beanClassName) {
305: this .beanClass = beanClassName;
306: }
307:
308: /**
309: * Return the class name of the wrapped bean.
310: */
311: public String getBeanClassName() {
312: if (this .beanClass instanceof Class) {
313: return ((Class) this .beanClass).getName();
314: } else {
315: return (String) this .beanClass;
316: }
317: }
318:
319: /**
320: * Determine the class of the wrapped bean, resolving it from a
321: * specified class name if necessary. Will also reload a specified
322: * Class from its name when called with the bean class already resolved.
323: * @param classLoader the ClassLoader to use for resolving a (potential) class name
324: * @return the resolved bean class
325: * @throws ClassNotFoundException if the class name could be resolved
326: */
327: public Class resolveBeanClass(ClassLoader classLoader)
328: throws ClassNotFoundException {
329: if (this .beanClass == null) {
330: return null;
331: }
332: Class resolvedClass = ClassUtils.forName(getBeanClassName(),
333: classLoader);
334: this .beanClass = resolvedClass;
335: return resolvedClass;
336: }
337:
338: /**
339: * Set the name of the target scope for the bean.
340: * <p>Default is "singleton"; the out-of-the-box alternative is "prototype".
341: * Extended bean factories might support further scopes.
342: * @see #SCOPE_SINGLETON
343: * @see #SCOPE_PROTOTYPE
344: */
345: public void setScope(String scope) {
346: Assert.notNull(scope, "Scope must not be null");
347: this .scope = scope;
348: this .singleton = SCOPE_SINGLETON.equals(scope);
349: this .prototype = SCOPE_PROTOTYPE.equals(scope);
350: }
351:
352: /**
353: * Return the name of the target scope for the bean.
354: */
355: public String getScope() {
356: return this .scope;
357: }
358:
359: /**
360: * Set if this a <b>Singleton</b>, with a single, shared instance returned
361: * on all calls. In case of "false", the BeanFactory will apply the <b>Prototype</b>
362: * design pattern, with each caller requesting an instance getting an independent
363: * instance. How this is exactly defined will depend on the BeanFactory.
364: * <p>"Singletons" are the commoner type, so the default is "true".
365: * Note that as of Spring 2.0, this flag is just an alternative way to
366: * specify scope="singleton" or scope="prototype".
367: * @see #setScope
368: * @see #SCOPE_SINGLETON
369: * @see #SCOPE_PROTOTYPE
370: */
371: public void setSingleton(boolean singleton) {
372: this .scope = (singleton ? SCOPE_SINGLETON : SCOPE_PROTOTYPE);
373: this .singleton = singleton;
374: this .prototype = !singleton;
375: }
376:
377: /**
378: * Return whether this a <b>Singleton</b>, with a single shared instance
379: * returned from all calls.
380: * @see #SCOPE_SINGLETON
381: */
382: public boolean isSingleton() {
383: return this .singleton;
384: }
385:
386: /**
387: * Return whether this a <b>Prototype</b>, with an independent instance
388: * returned for each call.
389: * @see #SCOPE_PROTOTYPE
390: */
391: public boolean isPrototype() {
392: return this .prototype;
393: }
394:
395: /**
396: * Set if this bean is "abstract", i.e. not meant to be instantiated itself but
397: * rather just serving as parent for concrete child bean definitions.
398: * <p>Default is "false". Specify true to tell the bean factory to not try to
399: * instantiate that particular bean in any case.
400: */
401: public void setAbstract(boolean abstractFlag) {
402: this .abstractFlag = abstractFlag;
403: }
404:
405: /**
406: * Return whether this bean is "abstract", i.e. not meant to be instantiated
407: * itself but rather just serving as parent for concrete child bean definitions.
408: */
409: public boolean isAbstract() {
410: return this .abstractFlag;
411: }
412:
413: /**
414: * Set whether this bean should be lazily initialized.
415: * <p>If <code>false</code>, the bean will get instantiated on startup by bean
416: * factories that perform eager initialization of singletons.
417: */
418: public void setLazyInit(boolean lazyInit) {
419: this .lazyInit = lazyInit;
420: }
421:
422: /**
423: * Return whether this bean should be lazily initialized, i.e. not
424: * eagerly instantiated on startup. Only applicable to a singleton bean.
425: */
426: public boolean isLazyInit() {
427: return this .lazyInit;
428: }
429:
430: /**
431: * Set whether this bean is a candidate for getting autowired into
432: * some other bean.
433: */
434: public void setAutowireCandidate(boolean autowireCandidate) {
435: this .autowireCandidate = autowireCandidate;
436: }
437:
438: /**
439: * Return whether this bean is a candidate for getting autowired into
440: * some other bean.
441: */
442: public boolean isAutowireCandidate() {
443: return this .autowireCandidate;
444: }
445:
446: /**
447: * Set the autowire mode. This determines whether any automagical detection
448: * and setting of bean references will happen. Default is AUTOWIRE_NO,
449: * which means there's no autowire.
450: * @param autowireMode the autowire mode to set.
451: * Must be one of the constants defined in this class.
452: * @see #AUTOWIRE_NO
453: * @see #AUTOWIRE_BY_NAME
454: * @see #AUTOWIRE_BY_TYPE
455: * @see #AUTOWIRE_CONSTRUCTOR
456: * @see #AUTOWIRE_AUTODETECT
457: */
458: public void setAutowireMode(int autowireMode) {
459: this .autowireMode = autowireMode;
460: }
461:
462: /**
463: * Return the autowire mode as specified in the bean definition.
464: */
465: public int getAutowireMode() {
466: return this .autowireMode;
467: }
468:
469: /**
470: * Return the resolved autowire code,
471: * (resolving AUTOWIRE_AUTODETECT to AUTOWIRE_CONSTRUCTOR or AUTOWIRE_BY_TYPE).
472: * @see #AUTOWIRE_AUTODETECT
473: * @see #AUTOWIRE_CONSTRUCTOR
474: * @see #AUTOWIRE_BY_TYPE
475: */
476: public int getResolvedAutowireMode() {
477: if (this .autowireMode == AUTOWIRE_AUTODETECT) {
478: // Work out whether to apply setter autowiring or constructor autowiring.
479: // If it has a no-arg constructor it's deemed to be setter autowiring,
480: // otherwise we'll try constructor autowiring.
481: Constructor[] constructors = getBeanClass()
482: .getConstructors();
483: for (int i = 0; i < constructors.length; i++) {
484: if (constructors[i].getParameterTypes().length == 0) {
485: return AUTOWIRE_BY_TYPE;
486: }
487: }
488: return AUTOWIRE_CONSTRUCTOR;
489: } else {
490: return this .autowireMode;
491: }
492: }
493:
494: /**
495: * Set the dependency check code.
496: * @param dependencyCheck the code to set.
497: * Must be one of the four constants defined in this class.
498: * @see #DEPENDENCY_CHECK_NONE
499: * @see #DEPENDENCY_CHECK_OBJECTS
500: * @see #DEPENDENCY_CHECK_SIMPLE
501: * @see #DEPENDENCY_CHECK_ALL
502: */
503: public void setDependencyCheck(int dependencyCheck) {
504: this .dependencyCheck = dependencyCheck;
505: }
506:
507: /**
508: * Return the dependency check code.
509: */
510: public int getDependencyCheck() {
511: return this .dependencyCheck;
512: }
513:
514: /**
515: * Set the names of the beans that this bean depends on being initialized.
516: * The bean factory will guarantee that these beans get initialized before.
517: * <p>Note that dependencies are normally expressed through bean properties or
518: * constructor arguments. This property should just be necessary for other kinds
519: * of dependencies like statics (*ugh*) or database preparation on startup.
520: */
521: public void setDependsOn(String[] dependsOn) {
522: this .dependsOn = dependsOn;
523: }
524:
525: /**
526: * Return the bean names that this bean depends on.
527: */
528: public String[] getDependsOn() {
529: return this .dependsOn;
530: }
531:
532: /**
533: * Specify constructor argument values for this bean.
534: */
535: public void setConstructorArgumentValues(
536: ConstructorArgumentValues constructorArgumentValues) {
537: this .constructorArgumentValues = (constructorArgumentValues != null ? constructorArgumentValues
538: : new ConstructorArgumentValues());
539: }
540:
541: /**
542: * Return constructor argument values for this bean (never <code>null</code>).
543: */
544: public ConstructorArgumentValues getConstructorArgumentValues() {
545: return this .constructorArgumentValues;
546: }
547:
548: /**
549: * Return if there are constructor argument values defined for this bean.
550: */
551: public boolean hasConstructorArgumentValues() {
552: return !this .constructorArgumentValues.isEmpty();
553: }
554:
555: /**
556: * Specify property values for this bean, if any.
557: */
558: public void setPropertyValues(MutablePropertyValues propertyValues) {
559: this .propertyValues = (propertyValues != null ? propertyValues
560: : new MutablePropertyValues());
561: }
562:
563: /**
564: * Return property values for this bean (never <code>null</code>).
565: */
566: public MutablePropertyValues getPropertyValues() {
567: return this .propertyValues;
568: }
569:
570: /**
571: * Specify method overrides for the bean, if any.
572: */
573: public void setMethodOverrides(MethodOverrides methodOverrides) {
574: this .methodOverrides = (methodOverrides != null ? methodOverrides
575: : new MethodOverrides());
576: }
577:
578: /**
579: * Return information about methods to be overridden by the IoC
580: * container. This will be empty if there are no method overrides.
581: * Never returns null.
582: */
583: public MethodOverrides getMethodOverrides() {
584: return this .methodOverrides;
585: }
586:
587: /**
588: * Specify the factory bean to use, if any.
589: */
590: public void setFactoryBeanName(String factoryBeanName) {
591: this .factoryBeanName = factoryBeanName;
592: }
593:
594: /**
595: * Returns the factory bean name, if any.
596: */
597: public String getFactoryBeanName() {
598: return this .factoryBeanName;
599: }
600:
601: /**
602: * Specify a factory method, if any. This method will be invoked with
603: * constructor arguments, or with no arguments if none are specified.
604: * The static method will be invoked on the specifed factory bean,
605: * if any, or on the local bean class else.
606: * @param factoryMethodName static factory method name, or <code>null</code> if
607: * normal constructor creation should be used
608: * @see #getBeanClass
609: */
610: public void setFactoryMethodName(String factoryMethodName) {
611: this .factoryMethodName = factoryMethodName;
612: }
613:
614: /**
615: * Return a factory method, if any.
616: */
617: public String getFactoryMethodName() {
618: return this .factoryMethodName;
619: }
620:
621: /**
622: * Set the name of the initializer method. The default is <code>null</code>
623: * in which case there is no initializer method.
624: */
625: public void setInitMethodName(String initMethodName) {
626: this .initMethodName = initMethodName;
627: }
628:
629: /**
630: * Return the name of the initializer method.
631: */
632: public String getInitMethodName() {
633: return this .initMethodName;
634: }
635:
636: /**
637: * Specify whether or not the configured init method is the default.
638: * Default value is <code>false</code>.
639: * @see #setInitMethodName
640: */
641: public void setEnforceInitMethod(boolean enforceInitMethod) {
642: this .enforceInitMethod = enforceInitMethod;
643: }
644:
645: /**
646: * Indicate whether the configured init method is the default.
647: * @see #getInitMethodName()
648: */
649: public boolean isEnforceInitMethod() {
650: return this .enforceInitMethod;
651: }
652:
653: /**
654: * Set the name of the destroy method. The default is <code>null</code>
655: * in which case there is no destroy method.
656: */
657: public void setDestroyMethodName(String destroyMethodName) {
658: this .destroyMethodName = destroyMethodName;
659: }
660:
661: /**
662: * Return the name of the destroy method.
663: */
664: public String getDestroyMethodName() {
665: return this .destroyMethodName;
666: }
667:
668: /**
669: * Specify whether or not the configured destroy method is the default.
670: * Default value is <code>false</code>.
671: * @see #setDestroyMethodName
672: */
673: public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
674: this .enforceDestroyMethod = enforceDestroyMethod;
675: }
676:
677: /**
678: * Indicate whether the configured destroy method is the default.
679: * @see #getDestroyMethodName
680: */
681: public boolean isEnforceDestroyMethod() {
682: return this .enforceDestroyMethod;
683: }
684:
685: /**
686: * Set whether this bean definition is 'synthetic', that is, not defined
687: * by the application itself (for example, an infrastructure bean such
688: * as a helper for auto-proxying, created through <code><aop:config></code>).
689: */
690: public void setSynthetic(boolean synthetic) {
691: this .synthetic = synthetic;
692: }
693:
694: /**
695: * Return whether this bean definition is 'synthetic', that is,
696: * not defined by the application itself.
697: */
698: public boolean isSynthetic() {
699: return this .synthetic;
700: }
701:
702: /**
703: * Set a description of the resource that this bean definition
704: * came from (for the purpose of showing context in case of errors).
705: */
706: public void setResourceDescription(String resourceDescription) {
707: this .resourceDescription = resourceDescription;
708: }
709:
710: /**
711: * Return a description of the resource that this bean definition
712: * came from.
713: */
714: public String getResourceDescription() {
715: return this .resourceDescription;
716: }
717:
718: /**
719: * Set the configuration source <code>Object</code> for this metadata element.
720: * <p>The exact type of the object will depend on the configuration mechanism used.
721: */
722: public void setSource(Object source) {
723: this .source = source;
724: }
725:
726: public Object getSource() {
727: return this .source;
728: }
729:
730: /**
731: * Set the role hint for this <code>BeanDefinition</code>.
732: */
733: public void setRole(int role) {
734: this .role = role;
735: }
736:
737: /**
738: * Return the role hint for this <code>BeanDefinition</code>.
739: */
740: public int getRole() {
741: return this .role;
742: }
743:
744: /**
745: * Validate this bean definition.
746: * @throws BeanDefinitionValidationException in case of validation failure
747: */
748: public void validate() throws BeanDefinitionValidationException {
749: if (!getMethodOverrides().isEmpty()
750: && getFactoryMethodName() != null) {
751: throw new BeanDefinitionValidationException(
752: "Cannot combine static factory method with method overrides: "
753: + "the static factory method must create the instance");
754: }
755:
756: if (hasBeanClass()) {
757: prepareMethodOverrides();
758: }
759: }
760:
761: /**
762: * Validate and prepare the method overrides defined for this bean.
763: * Checks for existence of a method with the specified name.
764: * @throws BeanDefinitionValidationException in case of validation failure
765: */
766: public void prepareMethodOverrides()
767: throws BeanDefinitionValidationException {
768: // Check that lookup methods exists.
769: for (Iterator it = getMethodOverrides().getOverrides()
770: .iterator(); it.hasNext();) {
771: MethodOverride mo = (MethodOverride) it.next();
772: prepareMethodOverride(mo);
773: }
774: }
775:
776: /**
777: * Validate and prepare the given method override.
778: * Checks for existence of a method with the specified name,
779: * marking it as not overloaded if none found.
780: * @param mo the MethodOverride object to validate
781: * @throws BeanDefinitionValidationException in case of validation failure
782: */
783: protected void prepareMethodOverride(MethodOverride mo)
784: throws BeanDefinitionValidationException {
785: int count = ClassUtils.getMethodCountForName(getBeanClass(), mo
786: .getMethodName());
787: if (count == 0) {
788: throw new BeanDefinitionValidationException(
789: "Invalid method override: no method with name '"
790: + mo.getMethodName() + "' on class ["
791: + getBeanClassName() + "]");
792: } else if (count == 1) {
793: // Mark override as not overloaded, to avoid the overhead of arg type checking.
794: mo.setOverloaded(false);
795: }
796: }
797:
798: public boolean equals(Object other) {
799: if (this == other) {
800: return true;
801: }
802: if (!(other instanceof AbstractBeanDefinition)) {
803: return false;
804: }
805:
806: AbstractBeanDefinition that = (AbstractBeanDefinition) other;
807:
808: if (!ObjectUtils.nullSafeEquals(this .beanClass, that.beanClass))
809: return false;
810: if (!ObjectUtils.nullSafeEquals(this .scope, that.scope))
811: return false;
812: if (this .abstractFlag != that.abstractFlag)
813: return false;
814: if (this .lazyInit != that.lazyInit)
815: return false;
816:
817: if (this .autowireCandidate != that.autowireCandidate)
818: return false;
819: if (this .autowireMode != that.autowireMode)
820: return false;
821: if (this .dependencyCheck != that.dependencyCheck)
822: return false;
823: if (!Arrays.equals(this .dependsOn, that.dependsOn))
824: return false;
825:
826: if (!ObjectUtils.nullSafeEquals(this .constructorArgumentValues,
827: that.constructorArgumentValues))
828: return false;
829: if (!ObjectUtils.nullSafeEquals(this .propertyValues,
830: that.propertyValues))
831: return false;
832: if (!ObjectUtils.nullSafeEquals(this .methodOverrides,
833: that.methodOverrides))
834: return false;
835:
836: if (!ObjectUtils.nullSafeEquals(this .factoryBeanName,
837: that.factoryBeanName))
838: return false;
839: if (!ObjectUtils.nullSafeEquals(this .factoryMethodName,
840: that.factoryMethodName))
841: return false;
842: if (!ObjectUtils.nullSafeEquals(this .initMethodName,
843: that.initMethodName))
844: return false;
845: if (this .enforceInitMethod != that.enforceInitMethod)
846: return false;
847: if (!ObjectUtils.nullSafeEquals(this .destroyMethodName,
848: that.destroyMethodName))
849: return false;
850: if (this .enforceDestroyMethod != that.enforceDestroyMethod)
851: return false;
852:
853: if (!ObjectUtils.nullSafeEquals(this .resourceDescription,
854: that.resourceDescription))
855: return false;
856: if (!ObjectUtils.nullSafeEquals(this .source, that.source))
857: return false;
858: if (this .role != that.role)
859: return false;
860:
861: return super .equals(other);
862: }
863:
864: public int hashCode() {
865: int hashCode = ObjectUtils.nullSafeHashCode(this .beanClass);
866: hashCode = 29 * hashCode
867: + ObjectUtils.nullSafeHashCode(this .scope);
868: hashCode = 29
869: * hashCode
870: + ObjectUtils
871: .nullSafeHashCode(this .constructorArgumentValues);
872: hashCode = 29 * hashCode
873: + ObjectUtils.nullSafeHashCode(this .propertyValues);
874: hashCode = 29 * hashCode
875: + ObjectUtils.nullSafeHashCode(this .factoryBeanName);
876: hashCode = 29 * hashCode
877: + ObjectUtils.nullSafeHashCode(this .factoryMethodName);
878: hashCode = 29 * hashCode + super .hashCode();
879: return hashCode;
880: }
881:
882: public String toString() {
883: StringBuffer sb = new StringBuffer("class [");
884: sb.append(getBeanClassName()).append("]");
885: sb.append("; scope=").append(this .scope);
886: sb.append("; abstract=").append(this .abstractFlag);
887: sb.append("; lazyInit=").append(this .lazyInit);
888: sb.append("; autowireCandidate=")
889: .append(this .autowireCandidate);
890: sb.append("; autowireMode=").append(this .autowireMode);
891: sb.append("; dependencyCheck=").append(this .dependencyCheck);
892: sb.append("; factoryBeanName=").append(this .factoryBeanName);
893: sb.append("; factoryMethodName=")
894: .append(this .factoryMethodName);
895: sb.append("; initMethodName=").append(this .initMethodName);
896: sb.append("; destroyMethodName=")
897: .append(this .destroyMethodName);
898: if (this .resourceDescription != null) {
899: sb.append("; defined in ").append(this.resourceDescription);
900: }
901: return sb.toString();
902: }
903:
904: }
|