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