001/*
002 * Copyright 2002-2020 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 *      https://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
017package org.springframework.beans.factory.support;
018
019import java.lang.reflect.Constructor;
020import java.util.Arrays;
021import java.util.LinkedHashMap;
022import java.util.LinkedHashSet;
023import java.util.Map;
024import java.util.Set;
025import java.util.function.Supplier;
026
027import org.springframework.beans.BeanMetadataAttributeAccessor;
028import org.springframework.beans.MutablePropertyValues;
029import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
030import org.springframework.beans.factory.config.BeanDefinition;
031import org.springframework.beans.factory.config.ConstructorArgumentValues;
032import org.springframework.core.ResolvableType;
033import org.springframework.core.io.DescriptiveResource;
034import org.springframework.core.io.Resource;
035import org.springframework.lang.Nullable;
036import org.springframework.util.Assert;
037import org.springframework.util.ClassUtils;
038import org.springframework.util.ObjectUtils;
039import org.springframework.util.StringUtils;
040
041/**
042 * Base class for concrete, full-fledged {@link BeanDefinition} classes,
043 * factoring out common properties of {@link GenericBeanDefinition},
044 * {@link RootBeanDefinition}, and {@link ChildBeanDefinition}.
045 *
046 * <p>The autowire constants match the ones defined in the
047 * {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
048 * interface.
049 *
050 * @author Rod Johnson
051 * @author Juergen Hoeller
052 * @author Rob Harrop
053 * @author Mark Fisher
054 * @see GenericBeanDefinition
055 * @see RootBeanDefinition
056 * @see ChildBeanDefinition
057 */
058@SuppressWarnings("serial")
059public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
060                implements BeanDefinition, Cloneable {
061
062        /**
063         * Constant for the default scope name: {@code ""}, equivalent to singleton
064         * status unless overridden from a parent bean definition (if applicable).
065         */
066        public static final String SCOPE_DEFAULT = "";
067
068        /**
069         * Constant that indicates no external autowiring at all.
070         * @see #setAutowireMode
071         */
072        public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
073
074        /**
075         * Constant that indicates autowiring bean properties by name.
076         * @see #setAutowireMode
077         */
078        public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
079
080        /**
081         * Constant that indicates autowiring bean properties by type.
082         * @see #setAutowireMode
083         */
084        public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
085
086        /**
087         * Constant that indicates autowiring a constructor.
088         * @see #setAutowireMode
089         */
090        public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
091
092        /**
093         * Constant that indicates determining an appropriate autowire strategy
094         * through introspection of the bean class.
095         * @see #setAutowireMode
096         * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
097         * use annotation-based autowiring for clearer demarcation of autowiring needs.
098         */
099        @Deprecated
100        public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
101
102        /**
103         * Constant that indicates no dependency check at all.
104         * @see #setDependencyCheck
105         */
106        public static final int DEPENDENCY_CHECK_NONE = 0;
107
108        /**
109         * Constant that indicates dependency checking for object references.
110         * @see #setDependencyCheck
111         */
112        public static final int DEPENDENCY_CHECK_OBJECTS = 1;
113
114        /**
115         * Constant that indicates dependency checking for "simple" properties.
116         * @see #setDependencyCheck
117         * @see org.springframework.beans.BeanUtils#isSimpleProperty
118         */
119        public static final int DEPENDENCY_CHECK_SIMPLE = 2;
120
121        /**
122         * Constant that indicates dependency checking for all properties
123         * (object references as well as "simple" properties).
124         * @see #setDependencyCheck
125         */
126        public static final int DEPENDENCY_CHECK_ALL = 3;
127
128        /**
129         * Constant that indicates the container should attempt to infer the
130         * {@link #setDestroyMethodName destroy method name} for a bean as opposed to
131         * explicit specification of a method name. The value {@value} is specifically
132         * designed to include characters otherwise illegal in a method name, ensuring
133         * no possibility of collisions with legitimately named methods having the same
134         * name.
135         * <p>Currently, the method names detected during destroy method inference
136         * are "close" and "shutdown", if present on the specific bean class.
137         */
138        public static final String INFER_METHOD = "(inferred)";
139
140
141        @Nullable
142        private volatile Object beanClass;
143
144        @Nullable
145        private String scope = SCOPE_DEFAULT;
146
147        private boolean abstractFlag = false;
148
149        @Nullable
150        private Boolean lazyInit;
151
152        private int autowireMode = AUTOWIRE_NO;
153
154        private int dependencyCheck = DEPENDENCY_CHECK_NONE;
155
156        @Nullable
157        private String[] dependsOn;
158
159        private boolean autowireCandidate = true;
160
161        private boolean primary = false;
162
163        private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
164
165        @Nullable
166        private Supplier<?> instanceSupplier;
167
168        private boolean nonPublicAccessAllowed = true;
169
170        private boolean lenientConstructorResolution = true;
171
172        @Nullable
173        private String factoryBeanName;
174
175        @Nullable
176        private String factoryMethodName;
177
178        @Nullable
179        private ConstructorArgumentValues constructorArgumentValues;
180
181        @Nullable
182        private MutablePropertyValues propertyValues;
183
184        private MethodOverrides methodOverrides = new MethodOverrides();
185
186        @Nullable
187        private String initMethodName;
188
189        @Nullable
190        private String destroyMethodName;
191
192        private boolean enforceInitMethod = true;
193
194        private boolean enforceDestroyMethod = true;
195
196        private boolean synthetic = false;
197
198        private int role = BeanDefinition.ROLE_APPLICATION;
199
200        @Nullable
201        private String description;
202
203        @Nullable
204        private Resource resource;
205
206
207        /**
208         * Create a new AbstractBeanDefinition with default settings.
209         */
210        protected AbstractBeanDefinition() {
211                this(null, null);
212        }
213
214        /**
215         * Create a new AbstractBeanDefinition with the given
216         * constructor argument values and property values.
217         */
218        protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
219                this.constructorArgumentValues = cargs;
220                this.propertyValues = pvs;
221        }
222
223        /**
224         * Create a new AbstractBeanDefinition as a deep copy of the given
225         * bean definition.
226         * @param original the original bean definition to copy from
227         */
228        protected AbstractBeanDefinition(BeanDefinition original) {
229                setParentName(original.getParentName());
230                setBeanClassName(original.getBeanClassName());
231                setScope(original.getScope());
232                setAbstract(original.isAbstract());
233                setFactoryBeanName(original.getFactoryBeanName());
234                setFactoryMethodName(original.getFactoryMethodName());
235                setRole(original.getRole());
236                setSource(original.getSource());
237                copyAttributesFrom(original);
238
239                if (original instanceof AbstractBeanDefinition) {
240                        AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
241                        if (originalAbd.hasBeanClass()) {
242                                setBeanClass(originalAbd.getBeanClass());
243                        }
244                        if (originalAbd.hasConstructorArgumentValues()) {
245                                setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
246                        }
247                        if (originalAbd.hasPropertyValues()) {
248                                setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
249                        }
250                        if (originalAbd.hasMethodOverrides()) {
251                                setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
252                        }
253                        Boolean lazyInit = originalAbd.getLazyInit();
254                        if (lazyInit != null) {
255                                setLazyInit(lazyInit);
256                        }
257                        setAutowireMode(originalAbd.getAutowireMode());
258                        setDependencyCheck(originalAbd.getDependencyCheck());
259                        setDependsOn(originalAbd.getDependsOn());
260                        setAutowireCandidate(originalAbd.isAutowireCandidate());
261                        setPrimary(originalAbd.isPrimary());
262                        copyQualifiersFrom(originalAbd);
263                        setInstanceSupplier(originalAbd.getInstanceSupplier());
264                        setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
265                        setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
266                        setInitMethodName(originalAbd.getInitMethodName());
267                        setEnforceInitMethod(originalAbd.isEnforceInitMethod());
268                        setDestroyMethodName(originalAbd.getDestroyMethodName());
269                        setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
270                        setSynthetic(originalAbd.isSynthetic());
271                        setResource(originalAbd.getResource());
272                }
273                else {
274                        setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
275                        setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
276                        setLazyInit(original.isLazyInit());
277                        setResourceDescription(original.getResourceDescription());
278                }
279        }
280
281
282        /**
283         * Override settings in this bean definition (presumably a copied parent
284         * from a parent-child inheritance relationship) from the given bean
285         * definition (presumably the child).
286         * <ul>
287         * <li>Will override beanClass if specified in the given bean definition.
288         * <li>Will always take {@code abstract}, {@code scope},
289         * {@code lazyInit}, {@code autowireMode}, {@code dependencyCheck},
290         * and {@code dependsOn} from the given bean definition.
291         * <li>Will add {@code constructorArgumentValues}, {@code propertyValues},
292         * {@code methodOverrides} from the given bean definition to existing ones.
293         * <li>Will override {@code factoryBeanName}, {@code factoryMethodName},
294         * {@code initMethodName}, and {@code destroyMethodName} if specified
295         * in the given bean definition.
296         * </ul>
297         */
298        public void overrideFrom(BeanDefinition other) {
299                if (StringUtils.hasLength(other.getBeanClassName())) {
300                        setBeanClassName(other.getBeanClassName());
301                }
302                if (StringUtils.hasLength(other.getScope())) {
303                        setScope(other.getScope());
304                }
305                setAbstract(other.isAbstract());
306                if (StringUtils.hasLength(other.getFactoryBeanName())) {
307                        setFactoryBeanName(other.getFactoryBeanName());
308                }
309                if (StringUtils.hasLength(other.getFactoryMethodName())) {
310                        setFactoryMethodName(other.getFactoryMethodName());
311                }
312                setRole(other.getRole());
313                setSource(other.getSource());
314                copyAttributesFrom(other);
315
316                if (other instanceof AbstractBeanDefinition) {
317                        AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
318                        if (otherAbd.hasBeanClass()) {
319                                setBeanClass(otherAbd.getBeanClass());
320                        }
321                        if (otherAbd.hasConstructorArgumentValues()) {
322                                getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
323                        }
324                        if (otherAbd.hasPropertyValues()) {
325                                getPropertyValues().addPropertyValues(other.getPropertyValues());
326                        }
327                        if (otherAbd.hasMethodOverrides()) {
328                                getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
329                        }
330                        Boolean lazyInit = otherAbd.getLazyInit();
331                        if (lazyInit != null) {
332                                setLazyInit(lazyInit);
333                        }
334                        setAutowireMode(otherAbd.getAutowireMode());
335                        setDependencyCheck(otherAbd.getDependencyCheck());
336                        setDependsOn(otherAbd.getDependsOn());
337                        setAutowireCandidate(otherAbd.isAutowireCandidate());
338                        setPrimary(otherAbd.isPrimary());
339                        copyQualifiersFrom(otherAbd);
340                        setInstanceSupplier(otherAbd.getInstanceSupplier());
341                        setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
342                        setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
343                        if (otherAbd.getInitMethodName() != null) {
344                                setInitMethodName(otherAbd.getInitMethodName());
345                                setEnforceInitMethod(otherAbd.isEnforceInitMethod());
346                        }
347                        if (otherAbd.getDestroyMethodName() != null) {
348                                setDestroyMethodName(otherAbd.getDestroyMethodName());
349                                setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
350                        }
351                        setSynthetic(otherAbd.isSynthetic());
352                        setResource(otherAbd.getResource());
353                }
354                else {
355                        getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
356                        getPropertyValues().addPropertyValues(other.getPropertyValues());
357                        setLazyInit(other.isLazyInit());
358                        setResourceDescription(other.getResourceDescription());
359                }
360        }
361
362        /**
363         * Apply the provided default values to this bean.
364         * @param defaults the default settings to apply
365         * @since 2.5
366         */
367        public void applyDefaults(BeanDefinitionDefaults defaults) {
368                Boolean lazyInit = defaults.getLazyInit();
369                if (lazyInit != null) {
370                        setLazyInit(lazyInit);
371                }
372                setAutowireMode(defaults.getAutowireMode());
373                setDependencyCheck(defaults.getDependencyCheck());
374                setInitMethodName(defaults.getInitMethodName());
375                setEnforceInitMethod(false);
376                setDestroyMethodName(defaults.getDestroyMethodName());
377                setEnforceDestroyMethod(false);
378        }
379
380
381        /**
382         * Specify the bean class name of this bean definition.
383         */
384        @Override
385        public void setBeanClassName(@Nullable String beanClassName) {
386                this.beanClass = beanClassName;
387        }
388
389        /**
390         * Return the current bean class name of this bean definition.
391         */
392        @Override
393        @Nullable
394        public String getBeanClassName() {
395                Object beanClassObject = this.beanClass;
396                if (beanClassObject instanceof Class) {
397                        return ((Class<?>) beanClassObject).getName();
398                }
399                else {
400                        return (String) beanClassObject;
401                }
402        }
403
404        /**
405         * Specify the class for this bean.
406         * @see #setBeanClassName(String)
407         */
408        public void setBeanClass(@Nullable Class<?> beanClass) {
409                this.beanClass = beanClass;
410        }
411
412        /**
413         * Return the specified class of the bean definition (assuming it is resolved already).
414         * <p><b>NOTE:</b> This is an initial class reference as declared in the bean metadata
415         * definition, potentially combined with a declared factory method or a
416         * {@link org.springframework.beans.factory.FactoryBean} which may lead to a different
417         * runtime type of the bean, or not being set at all in case of an instance-level
418         * factory method (which is resolved via {@link #getFactoryBeanName()} instead).
419         * <b>Do not use this for runtime type introspection of arbitrary bean definitions.</b>
420         * The recommended way to find out about the actual runtime type of a particular bean
421         * is a {@link org.springframework.beans.factory.BeanFactory#getType} call for the
422         * specified bean name; this takes all of the above cases into account and returns the
423         * type of object that a {@link org.springframework.beans.factory.BeanFactory#getBean}
424         * call is going to return for the same bean name.
425         * @return the resolved bean class (never {@code null})
426         * @throws IllegalStateException if the bean definition does not define a bean class,
427         * or a specified bean class name has not been resolved into an actual Class yet
428         * @see #getBeanClassName()
429         * @see #hasBeanClass()
430         * @see #setBeanClass(Class)
431         * @see #resolveBeanClass(ClassLoader)
432         */
433        public Class<?> getBeanClass() throws IllegalStateException {
434                Object beanClassObject = this.beanClass;
435                if (beanClassObject == null) {
436                        throw new IllegalStateException("No bean class specified on bean definition");
437                }
438                if (!(beanClassObject instanceof Class)) {
439                        throw new IllegalStateException(
440                                        "Bean class name [" + beanClassObject + "] has not been resolved into an actual Class");
441                }
442                return (Class<?>) beanClassObject;
443        }
444
445        /**
446         * Return whether this definition specifies a bean class.
447         * @see #getBeanClass()
448         * @see #setBeanClass(Class)
449         * @see #resolveBeanClass(ClassLoader)
450         */
451        public boolean hasBeanClass() {
452                return (this.beanClass instanceof Class);
453        }
454
455        /**
456         * Determine the class of the wrapped bean, resolving it from a
457         * specified class name if necessary. Will also reload a specified
458         * Class from its name when called with the bean class already resolved.
459         * @param classLoader the ClassLoader to use for resolving a (potential) class name
460         * @return the resolved bean class
461         * @throws ClassNotFoundException if the class name could be resolved
462         */
463        @Nullable
464        public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
465                String className = getBeanClassName();
466                if (className == null) {
467                        return null;
468                }
469                Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
470                this.beanClass = resolvedClass;
471                return resolvedClass;
472        }
473
474        /**
475         * Return a resolvable type for this bean definition.
476         * <p>This implementation delegates to {@link #getBeanClass()}.
477         * @since 5.2
478         */
479        @Override
480        public ResolvableType getResolvableType() {
481                return (hasBeanClass() ? ResolvableType.forClass(getBeanClass()) : ResolvableType.NONE);
482        }
483
484        /**
485         * Set the name of the target scope for the bean.
486         * <p>The default is singleton status, although this is only applied once
487         * a bean definition becomes active in the containing factory. A bean
488         * definition may eventually inherit its scope from a parent bean definition.
489         * For this reason, the default scope name is an empty string (i.e., {@code ""}),
490         * with singleton status being assumed until a resolved scope is set.
491         * @see #SCOPE_SINGLETON
492         * @see #SCOPE_PROTOTYPE
493         */
494        @Override
495        public void setScope(@Nullable String scope) {
496                this.scope = scope;
497        }
498
499        /**
500         * Return the name of the target scope for the bean.
501         */
502        @Override
503        @Nullable
504        public String getScope() {
505                return this.scope;
506        }
507
508        /**
509         * Return whether this a <b>Singleton</b>, with a single shared instance
510         * returned from all calls.
511         * @see #SCOPE_SINGLETON
512         */
513        @Override
514        public boolean isSingleton() {
515                return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
516        }
517
518        /**
519         * Return whether this a <b>Prototype</b>, with an independent instance
520         * returned for each call.
521         * @see #SCOPE_PROTOTYPE
522         */
523        @Override
524        public boolean isPrototype() {
525                return SCOPE_PROTOTYPE.equals(this.scope);
526        }
527
528        /**
529         * Set if this bean is "abstract", i.e. not meant to be instantiated itself but
530         * rather just serving as parent for concrete child bean definitions.
531         * <p>Default is "false". Specify true to tell the bean factory to not try to
532         * instantiate that particular bean in any case.
533         */
534        public void setAbstract(boolean abstractFlag) {
535                this.abstractFlag = abstractFlag;
536        }
537
538        /**
539         * Return whether this bean is "abstract", i.e. not meant to be instantiated
540         * itself but rather just serving as parent for concrete child bean definitions.
541         */
542        @Override
543        public boolean isAbstract() {
544                return this.abstractFlag;
545        }
546
547        /**
548         * Set whether this bean should be lazily initialized.
549         * <p>If {@code false}, the bean will get instantiated on startup by bean
550         * factories that perform eager initialization of singletons.
551         */
552        @Override
553        public void setLazyInit(boolean lazyInit) {
554                this.lazyInit = lazyInit;
555        }
556
557        /**
558         * Return whether this bean should be lazily initialized, i.e. not
559         * eagerly instantiated on startup. Only applicable to a singleton bean.
560         * @return whether to apply lazy-init semantics ({@code false} by default)
561         */
562        @Override
563        public boolean isLazyInit() {
564                return (this.lazyInit != null && this.lazyInit.booleanValue());
565        }
566
567        /**
568         * Return whether this bean should be lazily initialized, i.e. not
569         * eagerly instantiated on startup. Only applicable to a singleton bean.
570         * @return the lazy-init flag if explicitly set, or {@code null} otherwise
571         * @since 5.2
572         */
573        @Nullable
574        public Boolean getLazyInit() {
575                return this.lazyInit;
576        }
577
578        /**
579         * Set the autowire mode. This determines whether any automagical detection
580         * and setting of bean references will happen. Default is AUTOWIRE_NO
581         * which means there won't be convention-based autowiring by name or type
582         * (however, there may still be explicit annotation-driven autowiring).
583         * @param autowireMode the autowire mode to set.
584         * Must be one of the constants defined in this class.
585         * @see #AUTOWIRE_NO
586         * @see #AUTOWIRE_BY_NAME
587         * @see #AUTOWIRE_BY_TYPE
588         * @see #AUTOWIRE_CONSTRUCTOR
589         * @see #AUTOWIRE_AUTODETECT
590         */
591        public void setAutowireMode(int autowireMode) {
592                this.autowireMode = autowireMode;
593        }
594
595        /**
596         * Return the autowire mode as specified in the bean definition.
597         */
598        public int getAutowireMode() {
599                return this.autowireMode;
600        }
601
602        /**
603         * Return the resolved autowire code,
604         * (resolving AUTOWIRE_AUTODETECT to AUTOWIRE_CONSTRUCTOR or AUTOWIRE_BY_TYPE).
605         * @see #AUTOWIRE_AUTODETECT
606         * @see #AUTOWIRE_CONSTRUCTOR
607         * @see #AUTOWIRE_BY_TYPE
608         */
609        public int getResolvedAutowireMode() {
610                if (this.autowireMode == AUTOWIRE_AUTODETECT) {
611                        // Work out whether to apply setter autowiring or constructor autowiring.
612                        // If it has a no-arg constructor it's deemed to be setter autowiring,
613                        // otherwise we'll try constructor autowiring.
614                        Constructor<?>[] constructors = getBeanClass().getConstructors();
615                        for (Constructor<?> constructor : constructors) {
616                                if (constructor.getParameterCount() == 0) {
617                                        return AUTOWIRE_BY_TYPE;
618                                }
619                        }
620                        return AUTOWIRE_CONSTRUCTOR;
621                }
622                else {
623                        return this.autowireMode;
624                }
625        }
626
627        /**
628         * Set the dependency check code.
629         * @param dependencyCheck the code to set.
630         * Must be one of the four constants defined in this class.
631         * @see #DEPENDENCY_CHECK_NONE
632         * @see #DEPENDENCY_CHECK_OBJECTS
633         * @see #DEPENDENCY_CHECK_SIMPLE
634         * @see #DEPENDENCY_CHECK_ALL
635         */
636        public void setDependencyCheck(int dependencyCheck) {
637                this.dependencyCheck = dependencyCheck;
638        }
639
640        /**
641         * Return the dependency check code.
642         */
643        public int getDependencyCheck() {
644                return this.dependencyCheck;
645        }
646
647        /**
648         * Set the names of the beans that this bean depends on being initialized.
649         * The bean factory will guarantee that these beans get initialized first.
650         * <p>Note that dependencies are normally expressed through bean properties or
651         * constructor arguments. This property should just be necessary for other kinds
652         * of dependencies like statics (*ugh*) or database preparation on startup.
653         */
654        @Override
655        public void setDependsOn(@Nullable String... dependsOn) {
656                this.dependsOn = dependsOn;
657        }
658
659        /**
660         * Return the bean names that this bean depends on.
661         */
662        @Override
663        @Nullable
664        public String[] getDependsOn() {
665                return this.dependsOn;
666        }
667
668        /**
669         * Set whether this bean is a candidate for getting autowired into some other bean.
670         * <p>Note that this flag is designed to only affect type-based autowiring.
671         * It does not affect explicit references by name, which will get resolved even
672         * if the specified bean is not marked as an autowire candidate. As a consequence,
673         * autowiring by name will nevertheless inject a bean if the name matches.
674         * @see #AUTOWIRE_BY_TYPE
675         * @see #AUTOWIRE_BY_NAME
676         */
677        @Override
678        public void setAutowireCandidate(boolean autowireCandidate) {
679                this.autowireCandidate = autowireCandidate;
680        }
681
682        /**
683         * Return whether this bean is a candidate for getting autowired into some other bean.
684         */
685        @Override
686        public boolean isAutowireCandidate() {
687                return this.autowireCandidate;
688        }
689
690        /**
691         * Set whether this bean is a primary autowire candidate.
692         * <p>If this value is {@code true} for exactly one bean among multiple
693         * matching candidates, it will serve as a tie-breaker.
694         */
695        @Override
696        public void setPrimary(boolean primary) {
697                this.primary = primary;
698        }
699
700        /**
701         * Return whether this bean is a primary autowire candidate.
702         */
703        @Override
704        public boolean isPrimary() {
705                return this.primary;
706        }
707
708        /**
709         * Register a qualifier to be used for autowire candidate resolution,
710         * keyed by the qualifier's type name.
711         * @see AutowireCandidateQualifier#getTypeName()
712         */
713        public void addQualifier(AutowireCandidateQualifier qualifier) {
714                this.qualifiers.put(qualifier.getTypeName(), qualifier);
715        }
716
717        /**
718         * Return whether this bean has the specified qualifier.
719         */
720        public boolean hasQualifier(String typeName) {
721                return this.qualifiers.containsKey(typeName);
722        }
723
724        /**
725         * Return the qualifier mapped to the provided type name.
726         */
727        @Nullable
728        public AutowireCandidateQualifier getQualifier(String typeName) {
729                return this.qualifiers.get(typeName);
730        }
731
732        /**
733         * Return all registered qualifiers.
734         * @return the Set of {@link AutowireCandidateQualifier} objects.
735         */
736        public Set<AutowireCandidateQualifier> getQualifiers() {
737                return new LinkedHashSet<>(this.qualifiers.values());
738        }
739
740        /**
741         * Copy the qualifiers from the supplied AbstractBeanDefinition to this bean definition.
742         * @param source the AbstractBeanDefinition to copy from
743         */
744        public void copyQualifiersFrom(AbstractBeanDefinition source) {
745                Assert.notNull(source, "Source must not be null");
746                this.qualifiers.putAll(source.qualifiers);
747        }
748
749        /**
750         * Specify a callback for creating an instance of the bean,
751         * as an alternative to a declaratively specified factory method.
752         * <p>If such a callback is set, it will override any other constructor
753         * or factory method metadata. However, bean property population and
754         * potential annotation-driven injection will still apply as usual.
755         * @since 5.0
756         * @see #setConstructorArgumentValues(ConstructorArgumentValues)
757         * @see #setPropertyValues(MutablePropertyValues)
758         */
759        public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
760                this.instanceSupplier = instanceSupplier;
761        }
762
763        /**
764         * Return a callback for creating an instance of the bean, if any.
765         * @since 5.0
766         */
767        @Nullable
768        public Supplier<?> getInstanceSupplier() {
769                return this.instanceSupplier;
770        }
771
772        /**
773         * Specify whether to allow access to non-public constructors and methods,
774         * for the case of externalized metadata pointing to those. The default is
775         * {@code true}; switch this to {@code false} for public access only.
776         * <p>This applies to constructor resolution, factory method resolution,
777         * and also init/destroy methods. Bean property accessors have to be public
778         * in any case and are not affected by this setting.
779         * <p>Note that annotation-driven configuration will still access non-public
780         * members as far as they have been annotated. This setting applies to
781         * externalized metadata in this bean definition only.
782         */
783        public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
784                this.nonPublicAccessAllowed = nonPublicAccessAllowed;
785        }
786
787        /**
788         * Return whether to allow access to non-public constructors and methods.
789         */
790        public boolean isNonPublicAccessAllowed() {
791                return this.nonPublicAccessAllowed;
792        }
793
794        /**
795         * Specify whether to resolve constructors in lenient mode ({@code true},
796         * which is the default) or to switch to strict resolution (throwing an exception
797         * in case of ambiguous constructors that all match when converting the arguments,
798         * whereas lenient mode would use the one with the 'closest' type matches).
799         */
800        public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
801                this.lenientConstructorResolution = lenientConstructorResolution;
802        }
803
804        /**
805         * Return whether to resolve constructors in lenient mode or in strict mode.
806         */
807        public boolean isLenientConstructorResolution() {
808                return this.lenientConstructorResolution;
809        }
810
811        /**
812         * Specify the factory bean to use, if any.
813         * This the name of the bean to call the specified factory method on.
814         * @see #setFactoryMethodName
815         */
816        @Override
817        public void setFactoryBeanName(@Nullable String factoryBeanName) {
818                this.factoryBeanName = factoryBeanName;
819        }
820
821        /**
822         * Return the factory bean name, if any.
823         */
824        @Override
825        @Nullable
826        public String getFactoryBeanName() {
827                return this.factoryBeanName;
828        }
829
830        /**
831         * Specify a factory method, if any. This method will be invoked with
832         * constructor arguments, or with no arguments if none are specified.
833         * The method will be invoked on the specified factory bean, if any,
834         * or otherwise as a static method on the local bean class.
835         * @see #setFactoryBeanName
836         * @see #setBeanClassName
837         */
838        @Override
839        public void setFactoryMethodName(@Nullable String factoryMethodName) {
840                this.factoryMethodName = factoryMethodName;
841        }
842
843        /**
844         * Return a factory method, if any.
845         */
846        @Override
847        @Nullable
848        public String getFactoryMethodName() {
849                return this.factoryMethodName;
850        }
851
852        /**
853         * Specify constructor argument values for this bean.
854         */
855        public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
856                this.constructorArgumentValues = constructorArgumentValues;
857        }
858
859        /**
860         * Return constructor argument values for this bean (never {@code null}).
861         */
862        @Override
863        public ConstructorArgumentValues getConstructorArgumentValues() {
864                if (this.constructorArgumentValues == null) {
865                        this.constructorArgumentValues = new ConstructorArgumentValues();
866                }
867                return this.constructorArgumentValues;
868        }
869
870        /**
871         * Return if there are constructor argument values defined for this bean.
872         */
873        @Override
874        public boolean hasConstructorArgumentValues() {
875                return (this.constructorArgumentValues != null && !this.constructorArgumentValues.isEmpty());
876        }
877
878        /**
879         * Specify property values for this bean, if any.
880         */
881        public void setPropertyValues(MutablePropertyValues propertyValues) {
882                this.propertyValues = propertyValues;
883        }
884
885        /**
886         * Return property values for this bean (never {@code null}).
887         */
888        @Override
889        public MutablePropertyValues getPropertyValues() {
890                if (this.propertyValues == null) {
891                        this.propertyValues = new MutablePropertyValues();
892                }
893                return this.propertyValues;
894        }
895
896        /**
897         * Return if there are property values values defined for this bean.
898         * @since 5.0.2
899         */
900        @Override
901        public boolean hasPropertyValues() {
902                return (this.propertyValues != null && !this.propertyValues.isEmpty());
903        }
904
905        /**
906         * Specify method overrides for the bean, if any.
907         */
908        public void setMethodOverrides(MethodOverrides methodOverrides) {
909                this.methodOverrides = methodOverrides;
910        }
911
912        /**
913         * Return information about methods to be overridden by the IoC
914         * container. This will be empty if there are no method overrides.
915         * <p>Never returns {@code null}.
916         */
917        public MethodOverrides getMethodOverrides() {
918                return this.methodOverrides;
919        }
920
921        /**
922         * Return if there are method overrides defined for this bean.
923         * @since 5.0.2
924         */
925        public boolean hasMethodOverrides() {
926                return !this.methodOverrides.isEmpty();
927        }
928
929        /**
930         * Set the name of the initializer method.
931         * <p>The default is {@code null} in which case there is no initializer method.
932         */
933        @Override
934        public void setInitMethodName(@Nullable String initMethodName) {
935                this.initMethodName = initMethodName;
936        }
937
938        /**
939         * Return the name of the initializer method.
940         */
941        @Override
942        @Nullable
943        public String getInitMethodName() {
944                return this.initMethodName;
945        }
946
947        /**
948         * Specify whether or not the configured initializer method is the default.
949         * <p>The default value is {@code true} for a locally specified init method
950         * but switched to {@code false} for a shared setting in a defaults section
951         * (e.g. {@code bean init-method} versus {@code beans default-init-method}
952         * level in XML) which might not apply to all contained bean definitions.
953         * @see #setInitMethodName
954         * @see #applyDefaults
955         */
956        public void setEnforceInitMethod(boolean enforceInitMethod) {
957                this.enforceInitMethod = enforceInitMethod;
958        }
959
960        /**
961         * Indicate whether the configured initializer method is the default.
962         * @see #getInitMethodName()
963         */
964        public boolean isEnforceInitMethod() {
965                return this.enforceInitMethod;
966        }
967
968        /**
969         * Set the name of the destroy method.
970         * <p>The default is {@code null} in which case there is no destroy method.
971         */
972        @Override
973        public void setDestroyMethodName(@Nullable String destroyMethodName) {
974                this.destroyMethodName = destroyMethodName;
975        }
976
977        /**
978         * Return the name of the destroy method.
979         */
980        @Override
981        @Nullable
982        public String getDestroyMethodName() {
983                return this.destroyMethodName;
984        }
985
986        /**
987         * Specify whether or not the configured destroy method is the default.
988         * <p>The default value is {@code true} for a locally specified destroy method
989         * but switched to {@code false} for a shared setting in a defaults section
990         * (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
991         * level in XML) which might not apply to all contained bean definitions.
992         * @see #setDestroyMethodName
993         * @see #applyDefaults
994         */
995        public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
996                this.enforceDestroyMethod = enforceDestroyMethod;
997        }
998
999        /**
1000         * Indicate whether the configured destroy method is the default.
1001         * @see #getDestroyMethodName()
1002         */
1003        public boolean isEnforceDestroyMethod() {
1004                return this.enforceDestroyMethod;
1005        }
1006
1007        /**
1008         * Set whether this bean definition is 'synthetic', that is, not defined
1009         * by the application itself (for example, an infrastructure bean such
1010         * as a helper for auto-proxying, created through {@code <aop:config>}).
1011         */
1012        public void setSynthetic(boolean synthetic) {
1013                this.synthetic = synthetic;
1014        }
1015
1016        /**
1017         * Return whether this bean definition is 'synthetic', that is,
1018         * not defined by the application itself.
1019         */
1020        public boolean isSynthetic() {
1021                return this.synthetic;
1022        }
1023
1024        /**
1025         * Set the role hint for this {@code BeanDefinition}.
1026         */
1027        @Override
1028        public void setRole(int role) {
1029                this.role = role;
1030        }
1031
1032        /**
1033         * Return the role hint for this {@code BeanDefinition}.
1034         */
1035        @Override
1036        public int getRole() {
1037                return this.role;
1038        }
1039
1040        /**
1041         * Set a human-readable description of this bean definition.
1042         */
1043        @Override
1044        public void setDescription(@Nullable String description) {
1045                this.description = description;
1046        }
1047
1048        /**
1049         * Return a human-readable description of this bean definition.
1050         */
1051        @Override
1052        @Nullable
1053        public String getDescription() {
1054                return this.description;
1055        }
1056
1057        /**
1058         * Set the resource that this bean definition came from
1059         * (for the purpose of showing context in case of errors).
1060         */
1061        public void setResource(@Nullable Resource resource) {
1062                this.resource = resource;
1063        }
1064
1065        /**
1066         * Return the resource that this bean definition came from.
1067         */
1068        @Nullable
1069        public Resource getResource() {
1070                return this.resource;
1071        }
1072
1073        /**
1074         * Set a description of the resource that this bean definition
1075         * came from (for the purpose of showing context in case of errors).
1076         */
1077        public void setResourceDescription(@Nullable String resourceDescription) {
1078                this.resource = (resourceDescription != null ? new DescriptiveResource(resourceDescription) : null);
1079        }
1080
1081        /**
1082         * Return a description of the resource that this bean definition
1083         * came from (for the purpose of showing context in case of errors).
1084         */
1085        @Override
1086        @Nullable
1087        public String getResourceDescription() {
1088                return (this.resource != null ? this.resource.getDescription() : null);
1089        }
1090
1091        /**
1092         * Set the originating (e.g. decorated) BeanDefinition, if any.
1093         */
1094        public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
1095                this.resource = new BeanDefinitionResource(originatingBd);
1096        }
1097
1098        /**
1099         * Return the originating BeanDefinition, or {@code null} if none.
1100         * Allows for retrieving the decorated bean definition, if any.
1101         * <p>Note that this method returns the immediate originator. Iterate through the
1102         * originator chain to find the original BeanDefinition as defined by the user.
1103         */
1104        @Override
1105        @Nullable
1106        public BeanDefinition getOriginatingBeanDefinition() {
1107                return (this.resource instanceof BeanDefinitionResource ?
1108                                ((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
1109        }
1110
1111        /**
1112         * Validate this bean definition.
1113         * @throws BeanDefinitionValidationException in case of validation failure
1114         */
1115        public void validate() throws BeanDefinitionValidationException {
1116                if (hasMethodOverrides() && getFactoryMethodName() != null) {
1117                        throw new BeanDefinitionValidationException(
1118                                        "Cannot combine factory method with container-generated method overrides: " +
1119                                        "the factory method must create the concrete bean instance.");
1120                }
1121                if (hasBeanClass()) {
1122                        prepareMethodOverrides();
1123                }
1124        }
1125
1126        /**
1127         * Validate and prepare the method overrides defined for this bean.
1128         * Checks for existence of a method with the specified name.
1129         * @throws BeanDefinitionValidationException in case of validation failure
1130         */
1131        public void prepareMethodOverrides() throws BeanDefinitionValidationException {
1132                // Check that lookup methods exist and determine their overloaded status.
1133                if (hasMethodOverrides()) {
1134                        getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
1135                }
1136        }
1137
1138        /**
1139         * Validate and prepare the given method override.
1140         * Checks for existence of a method with the specified name,
1141         * marking it as not overloaded if none found.
1142         * @param mo the MethodOverride object to validate
1143         * @throws BeanDefinitionValidationException in case of validation failure
1144         */
1145        protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
1146                int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
1147                if (count == 0) {
1148                        throw new BeanDefinitionValidationException(
1149                                        "Invalid method override: no method with name '" + mo.getMethodName() +
1150                                        "' on class [" + getBeanClassName() + "]");
1151                }
1152                else if (count == 1) {
1153                        // Mark override as not overloaded, to avoid the overhead of arg type checking.
1154                        mo.setOverloaded(false);
1155                }
1156        }
1157
1158
1159        /**
1160         * Public declaration of Object's {@code clone()} method.
1161         * Delegates to {@link #cloneBeanDefinition()}.
1162         * @see Object#clone()
1163         */
1164        @Override
1165        public Object clone() {
1166                return cloneBeanDefinition();
1167        }
1168
1169        /**
1170         * Clone this bean definition.
1171         * To be implemented by concrete subclasses.
1172         * @return the cloned bean definition object
1173         */
1174        public abstract AbstractBeanDefinition cloneBeanDefinition();
1175
1176        @Override
1177        public boolean equals(@Nullable Object other) {
1178                if (this == other) {
1179                        return true;
1180                }
1181                if (!(other instanceof AbstractBeanDefinition)) {
1182                        return false;
1183                }
1184                AbstractBeanDefinition that = (AbstractBeanDefinition) other;
1185                return (ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()) &&
1186                                ObjectUtils.nullSafeEquals(this.scope, that.scope) &&
1187                                this.abstractFlag == that.abstractFlag &&
1188                                this.lazyInit == that.lazyInit &&
1189                                this.autowireMode == that.autowireMode &&
1190                                this.dependencyCheck == that.dependencyCheck &&
1191                                Arrays.equals(this.dependsOn, that.dependsOn) &&
1192                                this.autowireCandidate == that.autowireCandidate &&
1193                                ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers) &&
1194                                this.primary == that.primary &&
1195                                this.nonPublicAccessAllowed == that.nonPublicAccessAllowed &&
1196                                this.lenientConstructorResolution == that.lenientConstructorResolution &&
1197                                ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues) &&
1198                                ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues) &&
1199                                ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
1200                                ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
1201                                ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
1202                                ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) &&
1203                                this.enforceInitMethod == that.enforceInitMethod &&
1204                                ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) &&
1205                                this.enforceDestroyMethod == that.enforceDestroyMethod &&
1206                                this.synthetic == that.synthetic &&
1207                                this.role == that.role &&
1208                                super.equals(other));
1209        }
1210
1211        @Override
1212        public int hashCode() {
1213                int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
1214                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
1215                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
1216                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
1217                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
1218                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
1219                hashCode = 29 * hashCode + super.hashCode();
1220                return hashCode;
1221        }
1222
1223        @Override
1224        public String toString() {
1225                StringBuilder sb = new StringBuilder("class [");
1226                sb.append(getBeanClassName()).append("]");
1227                sb.append("; scope=").append(this.scope);
1228                sb.append("; abstract=").append(this.abstractFlag);
1229                sb.append("; lazyInit=").append(this.lazyInit);
1230                sb.append("; autowireMode=").append(this.autowireMode);
1231                sb.append("; dependencyCheck=").append(this.dependencyCheck);
1232                sb.append("; autowireCandidate=").append(this.autowireCandidate);
1233                sb.append("; primary=").append(this.primary);
1234                sb.append("; factoryBeanName=").append(this.factoryBeanName);
1235                sb.append("; factoryMethodName=").append(this.factoryMethodName);
1236                sb.append("; initMethodName=").append(this.initMethodName);
1237                sb.append("; destroyMethodName=").append(this.destroyMethodName);
1238                if (this.resource != null) {
1239                        sb.append("; defined in ").append(this.resource.getDescription());
1240                }
1241                return sb.toString();
1242        }
1243
1244}