1 16 17 package org.springframework.beans.factory.support; 18 19 import java.beans.PropertyDescriptor ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Modifier ; 23 import java.util.Arrays ; 24 import java.util.Collections ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import java.util.TreeSet ; 33 34 import org.springframework.beans.BeanUtils; 35 import org.springframework.beans.BeanWrapper; 36 import org.springframework.beans.BeanWrapperImpl; 37 import org.springframework.beans.BeansException; 38 import org.springframework.beans.FatalBeanException; 39 import org.springframework.beans.MutablePropertyValues; 40 import org.springframework.beans.PropertyValue; 41 import org.springframework.beans.PropertyValues; 42 import org.springframework.beans.factory.BeanClassLoaderAware; 43 import org.springframework.beans.factory.BeanCreationException; 44 import org.springframework.beans.factory.BeanCurrentlyInCreationException; 45 import org.springframework.beans.factory.BeanDefinitionStoreException; 46 import org.springframework.beans.factory.BeanFactory; 47 import org.springframework.beans.factory.BeanFactoryAware; 48 import org.springframework.beans.factory.BeanNameAware; 49 import org.springframework.beans.factory.FactoryBean; 50 import org.springframework.beans.factory.InitializingBean; 51 import org.springframework.beans.factory.UnsatisfiedDependencyException; 52 import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 53 import org.springframework.beans.factory.config.BeanPostProcessor; 54 import org.springframework.beans.factory.config.ConfigurableBeanFactory; 55 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; 56 import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; 57 import org.springframework.core.CollectionFactory; 58 import org.springframework.util.ReflectionUtils; 59 import org.springframework.util.StringUtils; 60 61 95 public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory 96 implements AutowireCapableBeanFactory { 97 98 private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); 99 100 101 private boolean allowCircularReferences = true; 102 103 107 private boolean allowRawInjectionDespiteWrapping = false; 108 109 113 private final Set ignoredDependencyTypes = new HashSet (); 114 115 119 private final Set ignoredDependencyInterfaces = new HashSet (); 120 121 122 private final Map factoryBeanInstanceCache = new HashMap (); 123 124 125 private final Map excludedPropertyDescriptorsCache = CollectionFactory.createIdentityMapIfPossible(16); 126 127 128 131 public AbstractAutowireCapableBeanFactory() { 132 super(); 133 ignoreDependencyInterface(BeanNameAware.class); 134 ignoreDependencyInterface(BeanFactoryAware.class); 135 ignoreDependencyInterface(BeanClassLoaderAware.class); 136 } 137 138 142 public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) { 143 this(); 144 setParentBeanFactory(parentBeanFactory); 145 } 146 147 148 153 public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { 154 this.instantiationStrategy = instantiationStrategy; 155 } 156 157 160 protected InstantiationStrategy getInstantiationStrategy() { 161 return instantiationStrategy; 162 } 163 164 177 public void setAllowCircularReferences(boolean allowCircularReferences) { 178 this.allowCircularReferences = allowCircularReferences; 179 } 180 181 195 public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) { 196 this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping; 197 } 198 199 203 public void ignoreDependencyType(Class type) { 204 this.ignoredDependencyTypes.add(type); 205 } 206 207 217 public void ignoreDependencyInterface(Class ifc) { 218 this.ignoredDependencyInterfaces.add(ifc); 219 } 220 221 222 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { 223 super.copyConfigurationFrom(otherFactory); 224 if (otherFactory instanceof AbstractAutowireCapableBeanFactory) { 225 AbstractAutowireCapableBeanFactory otherAutowireFactory = 226 (AbstractAutowireCapableBeanFactory) otherFactory; 227 this.instantiationStrategy = otherAutowireFactory.instantiationStrategy; 228 this.allowCircularReferences = otherAutowireFactory.allowCircularReferences; 229 this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes); 230 this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces); 231 } 232 } 233 234 235 239 public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) 240 throws BeansException { 241 242 RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); 244 bd.setSingleton(false); 245 return createBean(beanClass.getName(), bd, null); 246 } 247 248 public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) 249 throws BeansException { 250 251 RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); 253 bd.setSingleton(false); 254 if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) { 255 return autowireConstructor(beanClass.getName(), bd).getWrappedInstance(); 256 } 257 else { 258 Object bean = getInstantiationStrategy().instantiate(bd, null, this); 259 populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean)); 260 return bean; 261 } 262 } 263 264 public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) 265 throws BeansException { 266 267 if (autowireMode != AUTOWIRE_BY_NAME && autowireMode != AUTOWIRE_BY_TYPE) { 268 throw new IllegalArgumentException ("Just constants AUTOWIRE_BY_NAME and AUTOWIRE_BY_TYPE allowed"); 269 } 270 RootBeanDefinition bd = new RootBeanDefinition(existingBean.getClass(), autowireMode, dependencyCheck); 272 bd.setSingleton(false); 273 populateBean(existingBean.getClass().getName(), bd, new BeanWrapperImpl(existingBean)); 274 } 275 276 public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException { 277 RootBeanDefinition bd = getMergedBeanDefinition(beanName, true); 278 BeanWrapper bw = new BeanWrapperImpl(existingBean); 279 initBeanWrapper(bw); 280 applyPropertyValues(beanName, bd, bw, bd.getPropertyValues()); 281 } 282 283 public Object configureBean(Object existingBean, String beanName) throws BeansException { 284 RootBeanDefinition bd = getMergedBeanDefinition(beanName, true); 285 BeanWrapper bw = new BeanWrapperImpl(existingBean); 286 initBeanWrapper(bw); 287 populateBean(beanName, bd, bw); 288 return initializeBean(beanName, existingBean, bd); 289 } 290 291 public Object initializeBean(Object existingBean, String beanName) { 292 return initializeBean(beanName, existingBean, null); 293 } 294 295 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) 296 throws BeansException { 297 298 if (logger.isTraceEnabled()) { 299 logger.trace("Invoking BeanPostProcessors before initialization of bean '" + beanName + "'"); 300 } 301 Object result = existingBean; 302 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) { 303 BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); 304 result = beanProcessor.postProcessBeforeInitialization(result, beanName); 305 } 306 return result; 307 } 308 309 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 310 throws BeansException { 311 312 if (logger.isTraceEnabled()) { 313 logger.trace("Invoking BeanPostProcessors after initialization of bean '" + beanName + "'"); 314 } 315 Object result = existingBean; 316 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) { 317 BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); 318 result = beanProcessor.postProcessAfterInitialization(result, beanName); 319 } 320 return result; 321 } 322 323 324 328 337 protected Object createBean(String beanName, RootBeanDefinition mbd, Object [] args) 338 throws BeanCreationException { 339 340 if (mbd.getDependsOn() != null) { 342 for (int i = 0; i < mbd.getDependsOn().length; i++) { 343 getBean(mbd.getDependsOn()[i]); 344 } 345 } 346 347 if (logger.isDebugEnabled()) { 348 logger.debug("Creating instance of bean '" + beanName + "' with merged definition [" + mbd + "]"); 349 } 350 351 Class beanClass = resolveBeanClass(mbd, beanName); 353 354 try { 356 mbd.prepareMethodOverrides(); 357 } 358 catch (BeanDefinitionValidationException ex) { 359 throw new BeanDefinitionStoreException(mbd.getResourceDescription(), 360 beanName, "Validation of method overrides failed", ex); 361 } 362 363 String errorMessage = null; 364 365 try { 366 errorMessage = "BeanPostProcessor before instantiation of bean failed"; 368 369 if (beanClass != null && 371 !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 372 Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName); 373 if (bean != null) { 374 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 375 return bean; 376 } 377 } 378 379 errorMessage = "Instantiation of bean failed"; 381 382 BeanWrapper instanceWrapper = null; 383 if (mbd.isSingleton()) { 384 synchronized (getSingletonMutex()) { 385 instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName); 386 } 387 } 388 389 if (instanceWrapper == null) { 390 instanceWrapper = createBeanInstance(beanName, mbd, args); 391 } 392 Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); 393 394 if (mbd.isSingleton() && this.allowCircularReferences && 397 isSingletonCurrentlyInCreation(beanName)) { 398 if (logger.isDebugEnabled()) { 399 logger.debug("Eagerly caching bean '" + beanName + 400 "' to allow for resolving potential circular references"); 401 } 402 addSingleton(beanName, bean); 403 } 404 405 errorMessage = "Initialization of bean failed"; 407 408 boolean continueWithPropertyPopulation = true; 412 413 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 414 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) { 415 BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); 416 if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { 417 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; 418 if (!ibp.postProcessAfterInstantiation(bean, beanName)) { 419 continueWithPropertyPopulation = false; 420 break; 421 } 422 } 423 } 424 } 425 426 if (continueWithPropertyPopulation) { 427 populateBean(beanName, mbd, instanceWrapper); 428 } 429 430 Object originalBean = bean; 431 bean = initializeBean(beanName, bean, mbd); 432 433 if (!this.allowRawInjectionDespiteWrapping && originalBean != bean && 434 mbd.isSingleton() && hasDependentBean(beanName)) { 435 throw new BeanCurrentlyInCreationException(beanName, 436 "Bean with name '" + beanName + "' has been injected into other beans " + 437 getDependentBeans(beanName) + " in its raw version as part of a circular reference, " + 438 "but has eventually been wrapped (for example as part of auto-proxy creation). " + 439 "This means that said other beans do not use the final version of the bean. " + 440 "This is often the result of over-eager type matching - consider using " + 441 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); 442 } 443 444 registerDisposableBeanIfNecessary(beanName, originalBean, mbd); 446 447 return bean; 448 } 449 450 catch (BeanCreationException ex) { 451 throw ex; 452 } 453 catch (Throwable ex) { 454 throw new BeanCreationException( 455 mbd.getResourceDescription(), beanName, errorMessage, ex); 456 } 457 } 458 459 465 protected Class predictBeanType(String beanName, RootBeanDefinition mbd) { 466 Class beanClass = null; 467 if (mbd.getFactoryMethodName() != null) { 468 beanClass = getTypeForFactoryMethod(beanName, mbd); 469 } 470 else { 471 beanClass = resolveBeanClass(mbd, beanName); 472 } 473 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 476 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) { 477 BeanPostProcessor bp = (BeanPostProcessor) it.next(); 478 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 479 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 480 Class processedType = ibp.predictBeanType(beanClass, beanName); 481 if (processedType != null) { 482 return processedType; 483 } 484 } 485 } 486 } 487 return beanClass; 488 } 489 490 502 protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd) { 503 Class factoryClass = null; 504 boolean isStatic = true; 505 506 if (mbd.getFactoryBeanName() != null) { 507 factoryClass = getType(mbd.getFactoryBeanName()); 509 isStatic = false; 510 } 511 else { 512 factoryClass = resolveBeanClass(mbd, beanName); 514 } 515 516 if (factoryClass == null) { 517 return null; 518 } 519 520 int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount(); 523 Method [] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass); 524 Set returnTypes = new HashSet (1); 525 for (int i = 0; i < candidates.length; i++) { 526 Method factoryMethod = candidates[i]; 527 if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic && 528 factoryMethod.getName().equals(mbd.getFactoryMethodName()) && 529 factoryMethod.getParameterTypes().length >= minNrOfArgs) { 530 returnTypes.add(factoryMethod.getReturnType()); 531 } 532 } 533 534 if (returnTypes.size() == 1) { 535 return (Class ) returnTypes.iterator().next(); 537 } 538 else { 539 return null; 541 } 542 } 543 544 553 protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) { 554 FactoryBean fb = (mbd.isSingleton() ? 555 getSingletonFactoryBeanForTypeCheck(beanName, mbd) : 556 getNonSingletonFactoryBeanForTypeCheck(beanName, mbd)); 557 558 if (fb != null) { 559 try { 561 Class type = fb.getObjectType(); 562 if (type != null) { 563 return type; 564 } 565 } 566 catch (Throwable ex) { 567 logger.warn("FactoryBean threw exception from getObjectType, despite the contract saying " + 569 "that it should return null if the type of its object cannot be determined yet", ex); 570 } 571 } 572 573 return super.getTypeForFactoryBean(beanName, mbd); 575 } 576 577 578 582 591 private FactoryBean getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) { 592 synchronized (getSingletonMutex()) { 593 BeanWrapper bw = (BeanWrapper) this.factoryBeanInstanceCache.get(beanName); 594 if (bw != null) { 595 return (FactoryBean) bw.getWrappedInstance(); 596 } 597 if (isSingletonCurrentlyInCreation(beanName)) { 598 return null; 599 } 600 Object instance = null; 601 try { 602 beforeSingletonCreation(beanName); 604 Class beanClass = resolveBeanClass(mbd, beanName); 606 if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 607 Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName); 608 if (bean != null) { 609 instance = applyBeanPostProcessorsAfterInitialization(bean, beanName); 610 } 611 } 612 if (instance == null) { 613 bw = createBeanInstance(beanName, mbd, null); 614 instance = bw.getWrappedInstance(); 615 } 616 } 617 finally { 618 afterSingletonCreation(beanName); 620 } 621 if (!(instance instanceof FactoryBean)) { 622 throw new BeanCreationException(beanName, 623 "Bean instance of type [" + instance.getClass() + "] is not a FactoryBean"); 624 } 625 if (bw != null) { 626 this.factoryBeanInstanceCache.put(beanName, bw); 627 } 628 return (FactoryBean) instance; 629 } 630 } 631 632 641 private FactoryBean getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) { 642 if (isPrototypeCurrentlyInCreation(beanName)) { 643 return null; 644 } 645 Object instance = null; 646 try { 647 beforePrototypeCreation(beanName); 649 Class beanClass = resolveBeanClass(mbd, beanName); 651 if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 652 Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName); 653 if (bean != null) { 654 instance = applyBeanPostProcessorsAfterInitialization(bean, beanName); 655 } 656 } 657 if (instance == null) { 658 BeanWrapper bw = createBeanInstance(beanName, mbd, null); 659 instance = bw.getWrappedInstance(); 660 } 661 } 662 finally { 663 afterPrototypeCreation(beanName); 665 } 666 if (!(instance instanceof FactoryBean)) { 667 throw new BeanCreationException(beanName, 668 "Bean instance of type [" + instance.getClass() + "] is not a FactoryBean"); 669 } 670 return (FactoryBean) instance; 671 } 672 673 685 protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) 686 throws BeansException { 687 688 if (logger.isTraceEnabled()) { 689 logger.trace("Invoking BeanPostProcessors before instantiation of bean '" + beanName + "'"); 690 } 691 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) { 692 BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); 693 if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { 694 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; 695 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); 696 if (result != null) { 697 return result; 698 } 699 } 700 } 701 return null; 702 } 703 704 716 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object [] args) { 717 BeanWrapper instanceWrapper = null; 718 if (mbd.getFactoryMethodName() != null) { 719 instanceWrapper = instantiateUsingFactoryMethod(beanName, mbd, args); 720 } 721 else if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || 722 mbd.hasConstructorArgumentValues() ) { 723 instanceWrapper = autowireConstructor(beanName, mbd); 724 } 725 else { 726 instanceWrapper = instantiateBean(beanName, mbd); 728 } 729 return instanceWrapper; 730 } 731 732 738 protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { 739 Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); 740 BeanWrapper bw = new BeanWrapperImpl(beanInstance); 741 initBeanWrapper(bw); 742 return bw; 743 } 744 745 761 protected BeanWrapper instantiateUsingFactoryMethod( 762 String beanName, RootBeanDefinition mbd, Object [] explicitArgs) { 763 764 ConstructorResolver constructorResolver = new ConstructorResolverAdapter(); 765 return constructorResolver.instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); 766 } 767 768 779 protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd) { 780 ConstructorResolver constructorResolver = new ConstructorResolverAdapter(); 781 return constructorResolver.autowireConstructor(beanName, mbd); 782 } 783 784 791 protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { 792 PropertyValues pvs = mbd.getPropertyValues(); 793 794 if (bw == null) { 795 if (!pvs.isEmpty()) { 796 throw new BeanCreationException(beanName, "Cannot apply property values to null instance"); 797 } 798 else { 799 return; 801 } 802 } 803 804 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || 805 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { 806 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 807 808 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { 810 autowireByName(beanName, mbd, bw, newPvs); 811 } 812 813 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { 815 autowireByType(beanName, mbd, bw, newPvs); 816 } 817 818 pvs = newPvs; 819 } 820 821 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); 822 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); 823 824 if (hasInstAwareBpps || needsDepCheck) { 825 PropertyDescriptor [] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw); 826 if (hasInstAwareBpps) { 827 for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) { 828 BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); 829 if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { 830 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; 831 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 832 if (pvs == null) { 833 return; 834 } 835 } 836 } 837 } 838 if (needsDepCheck) { 839 checkDependencies(beanName, mbd, filteredPds, pvs); 840 } 841 } 842 843 applyPropertyValues(beanName, mbd, bw, pvs); 844 } 845 846 855 protected void autowireByName( 856 String beanName, RootBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { 857 858 String [] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); 859 for (int i = 0; i < propertyNames.length; i++) { 860 String propertyName = propertyNames[i]; 861 if (containsBean(propertyName)) { 862 Object bean = getBean(propertyName); 863 pvs.addPropertyValue(propertyName, bean); 864 if (mbd.isSingleton()) { 865 registerDependentBean(propertyName, beanName); 866 } 867 if (logger.isDebugEnabled()) { 868 logger.debug("Added autowiring by name from bean name '" + beanName + 869 "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); 870 } 871 } 872 else { 873 if (logger.isTraceEnabled()) { 874 logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + 875 "' by name: no matching bean found"); 876 } 877 } 878 } 879 } 880 881 892 protected void autowireByType( 893 String beanName, RootBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { 894 895 String [] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); 896 for (int i = 0; i < propertyNames.length; i++) { 897 String propertyName = propertyNames[i]; 898 Class requiredType = bw.getPropertyDescriptor(propertyName).getPropertyType(); 900 Map matchingBeans = findAutowireCandidates(beanName, requiredType); 901 int count = matchingBeans.size(); 903 if (count == 1) { 904 Map.Entry entry = (Map.Entry ) matchingBeans.entrySet().iterator().next(); 905 String autowiredBeanName = (String ) entry.getKey(); 906 Object autowiredBean = entry.getValue(); 907 pvs.addPropertyValue(propertyName, autowiredBean); 908 if (mbd.isSingleton()) { 909 registerDependentBean(autowiredBeanName, beanName); 910 } 911 if (logger.isDebugEnabled()) { 912 logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + 913 propertyName + "' to bean named '" + autowiredBeanName + "'"); 914 } 915 } 916 else if (count > 1) { 917 throw new UnsatisfiedDependencyException( 918 mbd.getResourceDescription(), beanName, propertyName, 919 "There are " + matchingBeans.size() + " beans of type [" + requiredType.getName() + 920 "] available for autowiring by type: " + matchingBeans.keySet() + 921 ". There should have been exactly 1 to be able to autowire property '" + 922 propertyName + "' of bean '" + beanName + "'. Consider using autowiring by name instead."); 923 } 924 else { 925 if (logger.isTraceEnabled()) { 926 logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + 927 "' by type: no matching bean found"); 928 } 929 } 930 } 931 } 932 933 942 protected String [] unsatisfiedNonSimpleProperties(RootBeanDefinition mbd, BeanWrapper bw) { 943 Set result = new TreeSet (); 944 PropertyValues pvs = mbd.getPropertyValues(); 945 PropertyDescriptor [] pds = bw.getPropertyDescriptors(); 946 for (int i = 0; i < pds.length; i++) { 947 if (pds[i].getWriteMethod() != null && !isExcludedFromDependencyCheck(pds[i]) && 948 !pvs.contains(pds[i].getName()) && !BeanUtils.isSimpleProperty(pds[i].getPropertyType())) { 949 result.add(pds[i].getName()); 950 } 951 } 952 return StringUtils.toStringArray(result); 953 } 954 955 963 protected PropertyDescriptor [] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) { 964 List pds = new LinkedList (Arrays.asList(bw.getPropertyDescriptors())); 965 for (Iterator it = pds.iterator(); it.hasNext();) { 966 PropertyDescriptor pd = (PropertyDescriptor ) it.next(); 967 if (isExcludedFromDependencyCheck(pd)) { 968 it.remove(); 969 } 970 } 971 return (PropertyDescriptor []) pds.toArray(new PropertyDescriptor [pds.size()]); 972 } 973 974 984 protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) { 985 synchronized (this.excludedPropertyDescriptorsCache) { 986 Boolean marker = (Boolean ) this.excludedPropertyDescriptorsCache.get(pd); 987 if (marker == null) { 988 marker = new Boolean (AutowireUtils.isExcludedFromDependencyCheck(pd) || 989 this.ignoredDependencyTypes.contains(pd.getPropertyType()) || 990 AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces)); 991 this.excludedPropertyDescriptorsCache.put(pd, marker); 992 } 993 return marker.booleanValue(); 994 } 995 } 996 997 1007 protected void checkDependencies( 1008 String beanName, RootBeanDefinition mbd, PropertyDescriptor [] pds, PropertyValues pvs) 1009 throws UnsatisfiedDependencyException { 1010 1011 int dependencyCheck = mbd.getDependencyCheck(); 1012 for (int i = 0; i < pds.length; i++) { 1013 if (pds[i].getWriteMethod() != null && !pvs.contains(pds[i].getName())) { 1014 boolean isSimple = BeanUtils.isSimpleProperty(pds[i].getPropertyType()); 1015 boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) || 1016 (isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) || 1017 (!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS); 1018 if (unsatisfied) { 1019 throw new UnsatisfiedDependencyException( 1020 mbd.getResourceDescription(), beanName, pds[i].getName(), 1021 "Set this property value or disable dependency checking for this bean."); 1022 } 1023 } 1024 } 1025 } 1026 1027 1035 protected void applyPropertyValues( 1036 String beanName, RootBeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { 1037 1038 if (pvs != null && !pvs.isEmpty()) { 1039 BeanDefinitionValueResolver valueResolver = 1040 new BeanDefinitionValueResolver(this, beanName, mbd, bw); 1041 1042 MutablePropertyValues deepCopy = new MutablePropertyValues(); 1044 PropertyValue[] pvArray = pvs.getPropertyValues(); 1045 for (int i = 0; i < pvArray.length; i++) { 1046 PropertyValue pv = pvArray[i]; 1047 Object resolvedValue = 1048 valueResolver.resolveValueIfNecessary("bean property '" + pv.getName() + "'", pv.getValue()); 1049 deepCopy.addPropertyValue(pv.getName(), resolvedValue); 1050 } 1051 1052 try { 1054 applyPropertyValues(bw, deepCopy); 1055 } 1056 catch (BeansException ex) { 1057 throw new BeanCreationException( 1059 mbd.getResourceDescription(), beanName, "Error setting property values", ex); 1060 } 1061 } 1062 } 1063 1064 1065 1082 protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { 1083 if (bean instanceof BeanNameAware) { 1084 if (logger.isTraceEnabled()) { 1085 logger.trace("Invoking setBeanName on BeanNameAware bean '" + beanName + "'"); 1086 } 1087 ((BeanNameAware) bean).setBeanName(beanName); 1088 } 1089 1090 if (bean instanceof BeanClassLoaderAware) { 1091 if (logger.isTraceEnabled()) { 1092 logger.trace("Invoking setBeanClassLoader on BeanClassLoaderAware bean '" + beanName + "'"); 1093 } 1094 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); 1095 } 1096 1097 if (bean instanceof BeanFactoryAware) { 1098 if (logger.isTraceEnabled()) { 1099 logger.trace("Invoking setBeanFactory on BeanFactoryAware bean '" + beanName + "'"); 1100 } 1101 ((BeanFactoryAware) bean).setBeanFactory(this); 1102 } 1103 1104 Object wrappedBean = bean; 1105 if (mbd == null || !mbd.isSynthetic()) { 1106 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 1107 } 1108 1109 try { 1110 invokeInitMethods(beanName, wrappedBean, mbd); 1111 } 1112 catch (Throwable ex) { 1113 throw new BeanCreationException( 1114 (mbd != null ? mbd.getResourceDescription() : null), 1115 beanName, "Invocation of init method failed", ex); 1116 } 1117 1118 if (mbd == null || !mbd.isSynthetic()) { 1119 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 1120 } 1121 return wrappedBean; 1122 } 1123 1124 1136 protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd) 1137 throws Throwable { 1138 1139 if (bean instanceof InitializingBean) { 1140 if (logger.isDebugEnabled()) { 1141 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); 1142 } 1143 ((InitializingBean) bean).afterPropertiesSet(); 1144 } 1145 1146 if (mbd != null && mbd.getInitMethodName() != null) { 1147 invokeCustomInitMethod( 1148 beanName, bean, mbd.getInitMethodName(), mbd.isEnforceInitMethod()); 1149 } 1150 } 1151 1152 1163 protected void invokeCustomInitMethod( 1164 String beanName, Object bean, String initMethodName, boolean enforceInitMethod) throws Throwable { 1165 1166 if (logger.isDebugEnabled()) { 1167 logger.debug("Invoking custom init method '" + initMethodName + 1168 "' on bean with name '" + beanName + "'"); 1169 } 1170 Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null); 1171 if (initMethod == null) { 1172 if (enforceInitMethod) { 1173 throw new NoSuchMethodException ("Couldn't find an init method named '" + initMethodName + 1174 "' on bean with name '" + beanName + "'"); 1175 } 1176 else { 1177 return; 1179 } 1180 } 1181 if (!Modifier.isPublic(initMethod.getModifiers()) || 1182 !Modifier.isPublic(initMethod.getDeclaringClass().getModifiers())) { 1183 initMethod.setAccessible(true); 1184 } 1185 try { 1186 initMethod.invoke(bean, (Object []) null); 1187 } 1188 catch (InvocationTargetException ex) { 1189 throw ex.getTargetException(); 1190 } 1191 } 1192 1193 1194 1200 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { 1201 return applyBeanPostProcessorsAfterInitialization(object, beanName); 1202 } 1203 1204 1207 protected void removeSingleton(String beanName) { 1208 super.removeSingleton(beanName); 1209 this.factoryBeanInstanceCache.remove(beanName); 1210 } 1211 1212 1213 1217 1230 protected Map findAutowireCandidates(String beanName, Class requiredType) throws BeansException { 1231 Map result = findMatchingBeans(requiredType); 1232 return (result != null ? result : Collections.EMPTY_MAP); 1233 } 1234 1235 1243 protected Map findMatchingBeans(Class requiredType) throws BeansException { 1244 throw new FatalBeanException("Bean lookup by type not supported by this factory"); 1245 } 1246 1247 1248 1252 1256 private class ConstructorResolverAdapter extends ConstructorResolver { 1257 1258 public ConstructorResolverAdapter() { 1259 super(AbstractAutowireCapableBeanFactory.this, getInstantiationStrategy()); 1260 } 1261 1262 protected Map findAutowireCandidates(String beanName, Class requiredType) throws BeansException { 1263 return AbstractAutowireCapableBeanFactory.this.findAutowireCandidates(beanName, requiredType); 1264 } 1265 } 1266 1267} 1268 | Popular Tags |