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}