1 16 17 package org.springframework.beans.factory.support; 18 19 import java.beans.PropertyEditor ; 20 import java.util.ArrayList ; 21 import java.util.Arrays ; 22 import java.util.Collections ; 23 import java.util.HashMap ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Set ; 29 30 import org.springframework.beans.BeanWrapper; 31 import org.springframework.beans.BeansException; 32 import org.springframework.beans.PropertyEditorRegistrar; 33 import org.springframework.beans.PropertyEditorRegistry; 34 import org.springframework.beans.PropertyValues; 35 import org.springframework.beans.SimpleTypeConverter; 36 import org.springframework.beans.TypeConverter; 37 import org.springframework.beans.TypeMismatchException; 38 import org.springframework.beans.factory.BeanCreationException; 39 import org.springframework.beans.factory.BeanCurrentlyInCreationException; 40 import org.springframework.beans.factory.BeanDefinitionStoreException; 41 import org.springframework.beans.factory.BeanFactory; 42 import org.springframework.beans.factory.BeanFactoryUtils; 43 import org.springframework.beans.factory.BeanIsAbstractException; 44 import org.springframework.beans.factory.BeanIsNotAFactoryException; 45 import org.springframework.beans.factory.BeanNotOfRequiredTypeException; 46 import org.springframework.beans.factory.CannotLoadBeanClassException; 47 import org.springframework.beans.factory.DisposableBean; 48 import org.springframework.beans.factory.FactoryBean; 49 import org.springframework.beans.factory.FactoryBeanNotInitializedException; 50 import org.springframework.beans.factory.NoSuchBeanDefinitionException; 51 import org.springframework.beans.factory.ObjectFactory; 52 import org.springframework.beans.factory.SmartFactoryBean; 53 import org.springframework.beans.factory.config.BeanDefinition; 54 import org.springframework.beans.factory.config.BeanPostProcessor; 55 import org.springframework.beans.factory.config.ConfigurableBeanFactory; 56 import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; 57 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; 58 import org.springframework.beans.factory.config.Scope; 59 import org.springframework.beans.propertyeditors.StringArrayPropertyEditor; 60 import org.springframework.core.CollectionFactory; 61 import org.springframework.core.MethodParameter; 62 import org.springframework.util.Assert; 63 import org.springframework.util.ClassUtils; 64 import org.springframework.util.StringUtils; 65 66 97 public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory { 98 99 100 private BeanFactory parentBeanFactory; 101 102 103 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 104 105 106 private boolean cacheBeanMetadata = true; 107 108 109 private final Map customEditors = new HashMap (); 110 111 112 private final Set propertyEditorRegistrars = CollectionFactory.createLinkedSetIfPossible(16); 113 114 115 private final List beanPostProcessors = new ArrayList (); 116 117 118 private boolean hasInstantiationAwareBeanPostProcessors; 119 120 121 private boolean hasDestructionAwareBeanPostProcessors; 122 123 124 private final Map scopes = new HashMap (); 125 126 127 private final Map aliasMap = new HashMap (); 128 129 130 private final Map mergedBeanDefinitions = CollectionFactory.createIdentityMapIfPossible(16); 131 132 133 private final Set alreadyCreated = Collections.synchronizedSet(new HashSet ()); 134 135 136 private final ThreadLocal prototypesCurrentlyInCreation = new ThreadLocal (); 137 138 139 private final Map factoryBeanObjectCache = new HashMap (); 140 141 142 145 public AbstractBeanFactory() { 146 } 147 148 153 public AbstractBeanFactory(BeanFactory parentBeanFactory) { 154 this.parentBeanFactory = parentBeanFactory; 155 } 156 157 158 162 public Object getBean(String name) throws BeansException { 163 return getBean(name, null, null); 164 } 165 166 public Object getBean(String name, Class requiredType) throws BeansException { 167 return getBean(name, requiredType, null); 168 } 169 170 178 public Object getBean(String name, Object [] args) throws BeansException { 179 return getBean(name, null, args); 180 } 181 182 191 public Object getBean(String name, Class requiredType, final Object [] args) throws BeansException { 192 final String beanName = transformedBeanName(name); 193 Object bean = null; 194 195 Object sharedInstance = getSingleton(beanName); 197 if (sharedInstance != null) { 198 if (isSingletonCurrentlyInCreation(beanName)) { 199 if (logger.isDebugEnabled()) { 200 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + 201 "' that is not fully initialized yet - a consequence of a circular reference"); 202 } 203 } 204 else { 205 if (logger.isDebugEnabled()) { 206 logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); 207 } 208 } 209 if (containsBeanDefinition(beanName)) { 210 RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false); 211 bean = getObjectForBeanInstance(sharedInstance, name, mbd); 212 } 213 else { 214 bean = getObjectForBeanInstance(sharedInstance, name, null); 215 } 216 } 217 218 else { 219 if (isPrototypeCurrentlyInCreation(beanName)) { 222 throw new BeanCurrentlyInCreationException(beanName); 223 } 224 225 BeanFactory parentBeanFactory = getParentBeanFactory(); 227 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 228 String nameToLookup = originalBeanName(name); 230 if (parentBeanFactory instanceof AbstractBeanFactory) { 231 return ((AbstractBeanFactory) parentBeanFactory).getBean(nameToLookup, requiredType, args); 233 } 234 else if (args == null) { 235 return parentBeanFactory.getBean(nameToLookup, requiredType); 237 } 238 else { 239 throw new NoSuchBeanDefinitionException(beanName, 240 "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments"); 241 } 242 } 243 244 this.alreadyCreated.add(beanName); 245 246 final RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false); 247 checkMergedBeanDefinition(mbd, beanName, args); 248 249 if (mbd.isSingleton()) { 251 sharedInstance = getSingleton(beanName, new ObjectFactory() { 252 public Object getObject() throws BeansException { 253 try { 254 return createBean(beanName, mbd, args); 255 } 256 catch (BeansException ex) { 257 destroySingleton(beanName); 261 throw ex; 262 } 263 } 264 }); 265 bean = getObjectForBeanInstance(sharedInstance, name, mbd); 266 } 267 268 else if (mbd.isPrototype()) { 269 Object prototypeInstance = null; 271 try { 272 beforePrototypeCreation(beanName); 273 prototypeInstance = createBean(beanName, mbd, args); 274 } 275 finally { 276 afterPrototypeCreation(beanName); 277 } 278 bean = getObjectForBeanInstance(prototypeInstance, name, mbd); 279 } 280 281 else { 282 String scopeName = mbd.getScope(); 283 final Scope scope = (Scope) this.scopes.get(scopeName); 284 if (scope == null) { 285 throw new IllegalStateException ("No Scope registered for scope '" + scopeName + "'"); 286 } 287 try { 288 Object scopedInstance = scope.get(beanName, new ObjectFactory() { 289 public Object getObject() throws BeansException { 290 beforePrototypeCreation(beanName); 291 try { 292 Object bean = createBean(beanName, mbd, args); 293 if (requiresDestruction(bean, mbd)) { 294 scope.registerDestructionCallback(beanName, 295 new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors())); 296 } 297 return bean; 298 } 299 finally { 300 afterPrototypeCreation(beanName); 301 } 302 } 303 }); 304 bean = getObjectForBeanInstance(scopedInstance, name, mbd); 305 } 306 catch (IllegalStateException ex) { 307 throw new BeanCreationException(beanName, 308 "Scope '" + scopeName + "' is not active for the current thread; " + 309 "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", 310 ex); 311 } 312 } 313 } 314 315 if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) { 317 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 318 } 319 return bean; 320 } 321 322 public boolean containsBean(String name) { 323 if (containsLocalBean(name)) { 324 return true; 325 } 326 BeanFactory parentBeanFactory = getParentBeanFactory(); 328 if (parentBeanFactory != null) { 329 return parentBeanFactory.containsBean(originalBeanName(name)); 330 } 331 return false; 332 } 333 334 public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { 335 String beanName = transformedBeanName(name); 336 337 Object beanInstance = getSingleton(beanName); 338 if (beanInstance != null) { 339 if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { 340 return ((FactoryBean) beanInstance).isSingleton(); 341 } 342 else { 343 return true; 344 } 345 } 346 347 else { 348 BeanFactory parentBeanFactory = getParentBeanFactory(); 350 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 351 return parentBeanFactory.isSingleton(originalBeanName(name)); 353 } 354 355 RootBeanDefinition bd = getMergedBeanDefinition(beanName, false); 356 357 if (bd.isSingleton() && !BeanFactoryUtils.isFactoryDereference(name)) { 359 if (isBeanClassMatch(beanName, bd, FactoryBean.class)) { 360 FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); 361 return factoryBean.isSingleton(); 362 } 363 } 364 365 return bd.isSingleton(); 366 } 367 } 368 369 public boolean isPrototype(String name) throws NoSuchBeanDefinitionException { 370 String beanName = transformedBeanName(name); 371 372 BeanFactory parentBeanFactory = getParentBeanFactory(); 373 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 374 return parentBeanFactory.isPrototype(originalBeanName(name)); 376 } 377 378 RootBeanDefinition bd = getMergedBeanDefinition(beanName, false); 379 380 if (bd.isSingleton() && !BeanFactoryUtils.isFactoryDereference(name)) { 382 if (isBeanClassMatch(beanName, bd, FactoryBean.class)) { 383 FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); 384 return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean) factoryBean).isPrototype()) || 385 !factoryBean.isSingleton()); 386 } 387 } 388 389 return bd.isPrototype(); 390 } 391 392 public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException { 393 if ((targetType == null || Object .class.equals(targetType)) && containsLocalBean(name)) { 394 return true; 395 } 396 397 String beanName = transformedBeanName(name); 398 399 Object beanInstance = getSingleton(beanName); 401 if (beanInstance != null) { 402 if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { 403 Class type = getTypeForFactoryBean((FactoryBean) beanInstance); 404 return (type != null && targetType.isAssignableFrom(type)); 405 } 406 else { 407 return targetType.isAssignableFrom(beanInstance.getClass()); 408 } 409 } 410 411 else { 412 BeanFactory parentBeanFactory = getParentBeanFactory(); 414 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 415 return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType); 417 } 418 419 RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false); 420 Class beanClass = predictBeanType(beanName, mbd); 421 422 if (beanClass == null) { 423 return false; 424 } 425 426 if (FactoryBean.class.isAssignableFrom(beanClass) && !BeanFactoryUtils.isFactoryDereference(name)) { 428 Class type = getTypeForFactoryBean(beanName, mbd); 430 return (type != null && targetType.isAssignableFrom(type)); 431 } 432 else { 433 return targetType.isAssignableFrom(beanClass); 434 } 435 } 436 } 437 438 public Class getType(String name) throws NoSuchBeanDefinitionException { 439 String beanName = transformedBeanName(name); 440 441 Object beanInstance = getSingleton(beanName); 443 if (beanInstance != null) { 444 if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { 445 return getTypeForFactoryBean((FactoryBean) beanInstance); 446 } 447 else { 448 return beanInstance.getClass(); 449 } 450 } 451 452 else { 453 BeanFactory parentBeanFactory = getParentBeanFactory(); 455 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 456 return parentBeanFactory.getType(originalBeanName(name)); 458 } 459 460 RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false); 461 Class beanClass = predictBeanType(beanName, mbd); 462 463 if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass) && 465 !BeanFactoryUtils.isFactoryDereference(name)) { 466 return getTypeForFactoryBean(beanName, mbd); 468 } 469 470 return beanClass; 471 } 472 } 473 474 public String [] getAliases(String name) { 475 String beanName = transformedBeanName(name); 476 List aliases = new ArrayList (); 477 boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX); 478 String fullBeanName = beanName; 479 if (factoryPrefix) { 480 fullBeanName = FACTORY_BEAN_PREFIX + beanName; 481 } 482 if (!fullBeanName.equals(name)) { 483 aliases.add(fullBeanName); 484 } 485 synchronized (this.aliasMap) { 486 for (Iterator it = this.aliasMap.entrySet().iterator(); it.hasNext();) { 487 Map.Entry entry = (Map.Entry ) it.next(); 488 if (entry.getValue().equals(beanName)) { 489 String key = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + entry.getKey(); 490 if (!key.equals(name)) { 491 aliases.add(key); 492 } 493 } 494 } 495 } 496 if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) { 497 BeanFactory parentBeanFactory = getParentBeanFactory(); 498 if (parentBeanFactory != null) { 499 aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName))); 500 } 501 } 502 return StringUtils.toStringArray(aliases); 503 } 504 505 506 510 public BeanFactory getParentBeanFactory() { 511 return this.parentBeanFactory; 512 } 513 514 public boolean containsLocalBean(String name) { 515 String beanName = transformedBeanName(name); 516 return (containsSingleton(beanName) || containsBeanDefinition(beanName)); 517 } 518 519 520 524 public void setParentBeanFactory(BeanFactory parentBeanFactory) { 525 if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) { 526 throw new IllegalStateException ("Already associated with parent BeanFactory: " + this.parentBeanFactory); 527 } 528 this.parentBeanFactory = parentBeanFactory; 529 } 530 531 public void setBeanClassLoader(ClassLoader beanClassLoader) { 532 this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader()); 533 } 534 535 public ClassLoader getBeanClassLoader() { 536 return this.beanClassLoader; 537 } 538 539 public void setCacheBeanMetadata(boolean cacheBeanMetadata) { 540 this.cacheBeanMetadata = cacheBeanMetadata; 541 } 542 543 public boolean isCacheBeanMetadata() { 544 return this.cacheBeanMetadata; 545 } 546 547 public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) { 548 Assert.notNull(registrar, "PropertyEditorRegistrar must not be null"); 549 this.propertyEditorRegistrars.add(registrar); 550 } 551 552 555 public Set getPropertyEditorRegistrars() { 556 return this.propertyEditorRegistrars; 557 } 558 559 public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor) { 560 Assert.notNull(requiredType, "Required type must not be null"); 561 Assert.notNull(propertyEditor, "PropertyEditor must not be null"); 562 this.customEditors.put(requiredType, propertyEditor); 563 } 564 565 569 public Map getCustomEditors() { 570 return this.customEditors; 571 } 572 573 public TypeConverter getTypeConverter() { 574 SimpleTypeConverter typeConverter = new SimpleTypeConverter(); 575 registerCustomEditors(typeConverter); 576 return typeConverter; 577 } 578 579 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { 580 Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); 581 this.beanPostProcessors.add(beanPostProcessor); 582 if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { 583 this.hasInstantiationAwareBeanPostProcessors = true; 584 } 585 if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { 586 this.hasDestructionAwareBeanPostProcessors = true; 587 } 588 } 589 590 public int getBeanPostProcessorCount() { 591 return this.beanPostProcessors.size(); 592 } 593 594 598 public List getBeanPostProcessors() { 599 return this.beanPostProcessors; 600 } 601 602 608 protected boolean hasInstantiationAwareBeanPostProcessors() { 609 return this.hasInstantiationAwareBeanPostProcessors; 610 } 611 612 618 protected boolean hasDestructionAwareBeanPostProcessors() { 619 return this.hasDestructionAwareBeanPostProcessors; 620 } 621 622 public void registerScope(String scopeName, Scope scope) { 623 Assert.notNull(scopeName, "Scope identifier must not be null"); 624 Assert.notNull(scope, "Scope must not be null"); 625 if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { 626 throw new IllegalArgumentException ("Cannot replace existing scopes 'singleton' and 'prototype'"); 627 } 628 this.scopes.put(scopeName, scope); 629 } 630 631 public String [] getRegisteredScopeNames() { 632 return StringUtils.toStringArray(this.scopes.keySet()); 633 } 634 635 public Scope getRegisteredScope(String scopeName) { 636 Assert.notNull(scopeName, "Scope identifier must not be null"); 637 return (Scope) this.scopes.get(scopeName); 638 } 639 640 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { 641 Assert.notNull(otherFactory, "BeanFactory must not be null"); 642 setBeanClassLoader(otherFactory.getBeanClassLoader()); 643 setCacheBeanMetadata(otherFactory.isCacheBeanMetadata()); 644 if (otherFactory instanceof AbstractBeanFactory) { 645 AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory; 646 this.customEditors.putAll(otherAbstractFactory.customEditors); 647 this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars); 648 this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors); 649 this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors || 650 otherAbstractFactory.hasInstantiationAwareBeanPostProcessors; 651 this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors || 652 otherAbstractFactory.hasDestructionAwareBeanPostProcessors; 653 this.scopes.putAll(otherAbstractFactory.scopes); 654 } 655 } 656 657 public void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException { 658 Assert.hasText(beanName, "'beanName' must not be empty"); 659 Assert.hasText(alias, "'alias' must not be empty"); 660 if (!alias.equals(beanName)) { 661 if (logger.isDebugEnabled()) { 663 logger.debug("Registering alias '" + alias + "' for bean with name '" + beanName + "'"); 664 } 665 synchronized (this.aliasMap) { 666 Object registeredName = this.aliasMap.get(alias); 667 if (registeredName != null && !registeredName.equals(beanName)) { 668 throw new BeanDefinitionStoreException("Cannot register alias '" + alias + "' for bean name '" + 669 beanName + "': It's already registered for bean name '" + registeredName + "'."); 670 } 671 this.aliasMap.put(alias, beanName); 672 } 673 } 674 } 675 676 682 protected void beforePrototypeCreation(String beanName) { 683 Set beanNames = (Set ) this.prototypesCurrentlyInCreation.get(); 684 if (beanNames == null) { 685 beanNames = new HashSet (); 686 this.prototypesCurrentlyInCreation.set(beanNames); 687 } 688 beanNames.add(beanName); 689 } 690 691 697 protected void afterPrototypeCreation(String beanName) { 698 Set beanNames = (Set ) this.prototypesCurrentlyInCreation.get(); 699 if (beanNames != null) { 700 beanNames.remove(beanName); 701 if (beanNames.isEmpty()) { 702 this.prototypesCurrentlyInCreation.set(null); 703 } 704 } 705 } 706 707 712 protected final boolean isPrototypeCurrentlyInCreation(String beanName) { 713 Set beanNames = (Set ) this.prototypesCurrentlyInCreation.get(); 714 return (beanNames != null ? beanNames.contains(beanName) : false); 715 } 716 717 public boolean isCurrentlyInCreation(String beanName) { 718 return isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName); 719 } 720 721 public void destroyBean(String beanName, Object beanInstance) { 722 destroyBean(beanName, beanInstance, getMergedBeanDefinition(beanName)); 723 } 724 725 732 protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) { 733 new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors()).destroy(); 734 } 735 736 public void destroyScopedBean(String beanName) { 737 RootBeanDefinition mbd = getMergedBeanDefinition(beanName); 738 if (mbd.isSingleton() || mbd.isPrototype()) { 739 throw new IllegalArgumentException ( 740 "Bean name '" + beanName + "' does not correspond to an object in a Scope"); 741 } 742 String scopeName = mbd.getScope(); 743 Scope scope = (Scope) this.scopes.get(scopeName); 744 if (scope == null) { 745 throw new IllegalStateException ("No Scope registered for scope '" + scopeName + "'"); 746 } 747 Object bean = scope.remove(beanName); 748 if (bean != null) { 749 destroyBean(beanName, bean, mbd); 750 } 751 } 752 753 754 758 763 protected String transformedBeanName(String name) { 764 String beanName = BeanFactoryUtils.transformedBeanName(name); 765 synchronized (this.aliasMap) { 767 String canonicalName = beanName; 768 String resolvedName = null; 769 do { 770 resolvedName = (String ) this.aliasMap.get(canonicalName); 771 if (resolvedName != null) { 772 canonicalName = resolvedName; 773 } 774 } 775 while (resolvedName != null); 776 return canonicalName; 777 } 778 } 779 780 784 protected String originalBeanName(String name) { 785 String beanName = transformedBeanName(name); 786 if (name.startsWith(FACTORY_BEAN_PREFIX)) { 787 beanName = FACTORY_BEAN_PREFIX + beanName; 788 } 789 return beanName; 790 } 791 792 797 protected boolean isAlias(String beanName) { 798 synchronized (this.aliasMap) { 799 return this.aliasMap.containsKey(beanName); 800 } 801 } 802 803 812 protected void initBeanWrapper(BeanWrapper bw) { 813 registerCustomEditors(bw); 814 } 815 816 824 protected void registerCustomEditors(PropertyEditorRegistry registry) { 825 registry.registerCustomEditor(String [].class, new StringArrayPropertyEditor()); 826 for (Iterator it = this.propertyEditorRegistrars.iterator(); it.hasNext();) { 827 PropertyEditorRegistrar registrar = (PropertyEditorRegistrar) it.next(); 828 registrar.registerCustomEditors(registry); 829 } 830 for (Iterator it = this.customEditors.entrySet().iterator(); it.hasNext();) { 831 Map.Entry entry = (Map.Entry ) it.next(); 832 Class clazz = (Class ) entry.getKey(); 833 PropertyEditor editor = (PropertyEditor ) entry.getValue(); 834 registry.registerCustomEditor(clazz, editor); 835 } 836 } 837 838 843 protected void applyPropertyValues(BeanWrapper bw, PropertyValues pv) { 844 if (!this.customEditors.isEmpty()) { 847 synchronized (this.customEditors) { 848 bw.setPropertyValues(pv); 849 } 850 } 851 else { 852 bw.setPropertyValues(pv); 853 } 854 } 855 856 869 protected Object doTypeConversionIfNecessary( 870 TypeConverter converter, Object value, Class targetType, MethodParameter methodParam) 871 throws TypeMismatchException { 872 873 if (!this.customEditors.isEmpty()) { 876 synchronized (this.customEditors) { 877 return converter.convertIfNecessary(value, targetType, methodParam); 878 } 879 } 880 else { 881 return converter.convertIfNecessary(value, targetType, methodParam); 882 } 883 } 884 885 886 894 public RootBeanDefinition getMergedBeanDefinition(String name) throws BeansException { 895 return getMergedBeanDefinition(name, false); 896 } 897 898 908 protected RootBeanDefinition getMergedBeanDefinition(String name, boolean includingAncestors) 909 throws BeansException { 910 911 String beanName = transformedBeanName(name); 912 913 if (includingAncestors && !containsBeanDefinition(beanName) && 915 getParentBeanFactory() instanceof AbstractBeanFactory) { 916 return ((AbstractBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName, true); 917 } 918 919 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 921 } 922 923 931 protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) 932 throws BeanDefinitionStoreException { 933 934 return getMergedBeanDefinition(beanName, bd, null); 935 } 936 937 947 protected RootBeanDefinition getMergedBeanDefinition( 948 String beanName, BeanDefinition bd, BeanDefinition containingBd) 949 throws BeanDefinitionStoreException { 950 951 synchronized (this.mergedBeanDefinitions) { 952 RootBeanDefinition mbd = (RootBeanDefinition) this.mergedBeanDefinitions.get(bd); 953 if (mbd == null) { 954 955 if (bd instanceof RootBeanDefinition) { 956 mbd = new RootBeanDefinition((RootBeanDefinition) bd); 958 } 959 960 else if (bd instanceof ChildBeanDefinition) { 961 ChildBeanDefinition cbd = (ChildBeanDefinition) bd; 963 RootBeanDefinition pbd = null; 964 try { 965 if (!beanName.equals(cbd.getParentName())) { 966 pbd = getMergedBeanDefinition(cbd.getParentName(), true); 967 } 968 else { 969 if (getParentBeanFactory() instanceof AbstractBeanFactory) { 970 AbstractBeanFactory parentFactory = (AbstractBeanFactory) getParentBeanFactory(); 971 pbd = parentFactory.getMergedBeanDefinition(cbd.getParentName(), true); 972 } 973 else { 974 throw new NoSuchBeanDefinitionException(cbd.getParentName(), 975 "Parent name '" + cbd.getParentName() + "' is equal to bean name '" + beanName + 976 "': cannot be resolved without an AbstractBeanFactory parent"); 977 } 978 } 979 } 980 catch (NoSuchBeanDefinitionException ex) { 981 throw new BeanDefinitionStoreException(cbd.getResourceDescription(), beanName, 982 "Could not resolve parent bean definition '" + cbd.getParentName() + "'", ex); 983 } 984 985 mbd = new RootBeanDefinition(pbd); 987 mbd.overrideFrom(cbd); 988 } 989 990 else { 991 throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, 992 "Definition is neither a RootBeanDefinition nor a ChildBeanDefinition: " + bd); 993 } 994 995 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { 1000 mbd.setSingleton(false); 1001 } 1002 1003 if (containingBd == null && isCacheBeanMetadata() && this.alreadyCreated.contains(beanName)) { 1006 this.mergedBeanDefinitions.put(bd, mbd); 1007 } 1008 } 1009 1010 return mbd; 1011 } 1012 } 1013 1014 1022 protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object [] args) 1023 throws BeanDefinitionStoreException { 1024 1025 if (mbd.isAbstract()) { 1027 throw new BeanIsAbstractException(beanName); 1028 } 1029 1030 if (args != null) { 1033 if (mbd.isSingleton()) { 1034 throw new BeanDefinitionStoreException( 1035 "Cannot specify arguments in the getBean() method when referring to a singleton bean definition"); 1036 } 1037 else if (mbd.getFactoryMethodName() == null) { 1038 throw new BeanDefinitionStoreException( 1039 "Can only specify arguments in the getBean() method in conjunction with a factory method"); 1040 } 1041 } 1042 } 1043 1044 1053 protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName) throws CannotLoadBeanClassException { 1054 if (mbd.hasBeanClass()) { 1055 return mbd.getBeanClass(); 1056 } 1057 try { 1058 return mbd.resolveBeanClass(getBeanClassLoader()); 1059 } 1060 catch (ClassNotFoundException ex) { 1061 throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); 1062 } 1063 catch (LinkageError err) { 1064 throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); 1065 } 1066 } 1067 1068 1069 1083 protected boolean isBeanClassMatch(String beanName, RootBeanDefinition mbd, Class targetType) 1084 throws CannotLoadBeanClassException { 1085 1086 Class beanClass = resolveBeanClass(mbd, beanName); 1087 return (beanClass != null && targetType.isAssignableFrom(beanClass)); 1088 } 1089 1090 1103 protected Class predictBeanType(String beanName, RootBeanDefinition mbd) { 1104 if (mbd.getFactoryMethodName() == null) { 1105 return resolveBeanClass(mbd, beanName); 1106 } 1107 return null; 1108 } 1109 1110 1125 protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) { 1126 try { 1127 FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); 1128 return getTypeForFactoryBean(factoryBean); 1129 } 1130 catch (BeanCreationException ex) { 1131 logger.debug("Ignoring bean creation exception on FactoryBean type check", ex); 1133 return null; 1134 } 1135 } 1136 1137 1143 protected Class getTypeForFactoryBean(FactoryBean factoryBean) { 1144 try { 1145 return factoryBean.getObjectType(); 1146 } 1147 catch (Throwable ex) { 1148 logger.warn("FactoryBean threw exception from getObjectType, despite the contract saying " + 1150 "that it should return null if the type of its object cannot be determined yet", ex); 1151 return null; 1152 } 1153 } 1154 1155 1156 1164 protected Object getObjectForBeanInstance(Object beanInstance, String name, RootBeanDefinition mbd) { 1165 String beanName = transformedBeanName(name); 1166 1167 if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { 1170 throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); 1171 } 1172 1173 boolean shared = (mbd == null || mbd.isSingleton()); 1174 Object object = beanInstance; 1175 1176 if (beanInstance instanceof FactoryBean) { 1180 if (!BeanFactoryUtils.isFactoryDereference(name)) { 1181 FactoryBean factory = (FactoryBean) beanInstance; 1183 if (logger.isTraceEnabled()) { 1184 logger.trace("Bean with name '" + beanName + "' is a factory bean"); 1185 } 1186 if (shared && factory.isSingleton()) { 1188 synchronized (getSingletonMutex()) { 1189 object = this.factoryBeanObjectCache.get(beanName); 1190 if (object == null) { 1191 object = getObjectFromFactoryBean(factory, beanName, mbd); 1192 this.factoryBeanObjectCache.put(beanName, object); 1193 } 1194 } 1195 } 1196 else { 1197 object = getObjectFromFactoryBean(factory, beanName, mbd); 1198 } 1199 } 1200 else { 1201 if (logger.isTraceEnabled()) { 1203 logger.trace("Calling code asked for FactoryBean instance for name '" + beanName + "'"); 1204 } 1205 } 1206 } 1207 1208 return object; 1209 } 1210 1211 1220 private Object getObjectFromFactoryBean(FactoryBean factory, String beanName, RootBeanDefinition mbd) 1221 throws BeanCreationException { 1222 1223 Object object; 1224 1225 try { 1226 object = factory.getObject(); 1227 } 1228 catch (FactoryBeanNotInitializedException ex) { 1229 throw new BeanCurrentlyInCreationException(beanName, ex.toString()); 1230 } 1231 catch (Throwable ex) { 1232 throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); 1233 } 1234 1235 if (object == null && isSingletonCurrentlyInCreation(beanName)) { 1238 throw new BeanCurrentlyInCreationException( 1239 beanName, "FactoryBean which is currently in creation returned null from getObject"); 1240 } 1241 1242 if (object != null && (mbd == null || !mbd.isSynthetic())) { 1243 try { 1244 object = postProcessObjectFromFactoryBean(object, beanName); 1245 } 1246 catch (Throwable ex) { 1247 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 1248 "Post-processing of the FactoryBean's object failed", ex); 1249 } 1250 } 1251 1252 return object; 1253 } 1254 1255 1265 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException { 1266 return object; 1267 } 1268 1269 1276 public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { 1277 String beanName = transformedBeanName(name); 1278 1279 Object beanInstance = getSingleton(beanName); 1280 if (beanInstance != null) { 1281 return (beanInstance instanceof FactoryBean); 1282 } 1283 1284 if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof AbstractBeanFactory) { 1286 return ((AbstractBeanFactory) getParentBeanFactory()).isFactoryBean(name); 1288 } 1289 1290 RootBeanDefinition bd = getMergedBeanDefinition(beanName, false); 1291 return isBeanClassMatch(beanName, bd, FactoryBean.class); 1292 } 1293 1294 1295 1301 protected boolean isBeanNameInUse(String beanName) { 1302 return containsLocalBean(beanName) || hasDependentBean(beanName); 1303 } 1304 1305 1315 protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { 1316 return (bean instanceof DisposableBean || mbd.getDestroyMethodName() != null || 1317 hasDestructionAwareBeanPostProcessors()); 1318 } 1319 1320 1334 protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { 1335 if (mbd.isSingleton() && requiresDestruction(bean, mbd)) { 1336 registerDisposableBean(beanName, 1340 new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors())); 1341 1342 String [] dependsOn = mbd.getDependsOn(); 1345 if (dependsOn != null) { 1346 for (int i = 0; i < dependsOn.length; i++) { 1347 registerDependentBean(dependsOn[i], beanName); 1348 } 1349 } 1350 } 1351 } 1352 1353 1356 protected void removeSingleton(String beanName) { 1357 super.removeSingleton(beanName); 1358 this.factoryBeanObjectCache.remove(beanName); 1359 } 1360 1361 1362 1366 1381 protected abstract boolean containsBeanDefinition(String beanName); 1382 1383 1402 protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException; 1403 1404 1418 protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object [] args) 1419 throws BeanCreationException; 1420 1421} 1422 | Popular Tags |