001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory.support; 018 019import java.beans.PropertyDescriptor; 020import java.lang.reflect.Constructor; 021import java.lang.reflect.InvocationTargetException; 022import java.lang.reflect.Method; 023import java.lang.reflect.Modifier; 024import java.security.AccessController; 025import java.security.PrivilegedAction; 026import java.security.PrivilegedActionException; 027import java.security.PrivilegedExceptionAction; 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.HashSet; 032import java.util.Iterator; 033import java.util.LinkedHashSet; 034import java.util.List; 035import java.util.Set; 036import java.util.TreeSet; 037import java.util.concurrent.ConcurrentHashMap; 038import java.util.concurrent.ConcurrentMap; 039 040import org.springframework.beans.BeanUtils; 041import org.springframework.beans.BeanWrapper; 042import org.springframework.beans.BeanWrapperImpl; 043import org.springframework.beans.BeansException; 044import org.springframework.beans.MutablePropertyValues; 045import org.springframework.beans.PropertyAccessorUtils; 046import org.springframework.beans.PropertyValue; 047import org.springframework.beans.PropertyValues; 048import org.springframework.beans.TypeConverter; 049import org.springframework.beans.factory.Aware; 050import org.springframework.beans.factory.BeanClassLoaderAware; 051import org.springframework.beans.factory.BeanCreationException; 052import org.springframework.beans.factory.BeanCurrentlyInCreationException; 053import org.springframework.beans.factory.BeanDefinitionStoreException; 054import org.springframework.beans.factory.BeanFactory; 055import org.springframework.beans.factory.BeanFactoryAware; 056import org.springframework.beans.factory.BeanNameAware; 057import org.springframework.beans.factory.FactoryBean; 058import org.springframework.beans.factory.InitializingBean; 059import org.springframework.beans.factory.ObjectFactory; 060import org.springframework.beans.factory.UnsatisfiedDependencyException; 061import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 062import org.springframework.beans.factory.config.BeanDefinition; 063import org.springframework.beans.factory.config.BeanPostProcessor; 064import org.springframework.beans.factory.config.ConfigurableBeanFactory; 065import org.springframework.beans.factory.config.ConstructorArgumentValues; 066import org.springframework.beans.factory.config.DependencyDescriptor; 067import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; 068import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; 069import org.springframework.beans.factory.config.TypedStringValue; 070import org.springframework.core.DefaultParameterNameDiscoverer; 071import org.springframework.core.GenericTypeResolver; 072import org.springframework.core.MethodParameter; 073import org.springframework.core.ParameterNameDiscoverer; 074import org.springframework.core.PriorityOrdered; 075import org.springframework.core.ResolvableType; 076import org.springframework.util.ClassUtils; 077import org.springframework.util.ObjectUtils; 078import org.springframework.util.ReflectionUtils; 079import org.springframework.util.StringUtils; 080 081/** 082 * Abstract bean factory superclass that implements default bean creation, 083 * with the full capabilities specified by the {@link RootBeanDefinition} class. 084 * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory} 085 * interface in addition to AbstractBeanFactory's {@link #createBean} method. 086 * 087 * <p>Provides bean creation (with constructor resolution), property population, 088 * wiring (including autowiring), and initialization. Handles runtime bean 089 * references, resolves managed collections, calls initialization methods, etc. 090 * Supports autowiring constructors, properties by name, and properties by type. 091 * 092 * <p>The main template method to be implemented by subclasses is 093 * {@link #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)}, 094 * used for autowiring by type. In case of a factory which is capable of searching 095 * its bean definitions, matching beans will typically be implemented through such 096 * a search. For other factory styles, simplified matching algorithms can be implemented. 097 * 098 * <p>Note that this class does <i>not</i> assume or implement bean definition 099 * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation 100 * of the {@link org.springframework.beans.factory.ListableBeanFactory} and 101 * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI 102 * view of such a factory, respectively. 103 * 104 * @author Rod Johnson 105 * @author Juergen Hoeller 106 * @author Rob Harrop 107 * @author Mark Fisher 108 * @author Costin Leau 109 * @author Chris Beams 110 * @author Sam Brannen 111 * @since 13.02.2004 112 * @see RootBeanDefinition 113 * @see DefaultListableBeanFactory 114 * @see BeanDefinitionRegistry 115 */ 116public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory 117 implements AutowireCapableBeanFactory { 118 119 /** Strategy for creating bean instances */ 120 private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); 121 122 /** Resolver strategy for method parameter names */ 123 private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); 124 125 /** Whether to automatically try to resolve circular references between beans */ 126 private boolean allowCircularReferences = true; 127 128 /** 129 * Whether to resort to injecting a raw bean instance in case of circular reference, 130 * even if the injected bean eventually got wrapped. 131 */ 132 private boolean allowRawInjectionDespiteWrapping = false; 133 134 /** 135 * Dependency types to ignore on dependency check and autowire, as Set of 136 * Class objects: for example, String. Default is none. 137 */ 138 private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>(); 139 140 /** 141 * Dependency interfaces to ignore on dependency check and autowire, as Set of 142 * Class objects. By default, only the BeanFactory interface is ignored. 143 */ 144 private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>(); 145 146 /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */ 147 private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = 148 new ConcurrentHashMap<String, BeanWrapper>(16); 149 150 /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */ 151 private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache = 152 new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(256); 153 154 155 /** 156 * Create a new AbstractAutowireCapableBeanFactory. 157 */ 158 public AbstractAutowireCapableBeanFactory() { 159 super(); 160 ignoreDependencyInterface(BeanNameAware.class); 161 ignoreDependencyInterface(BeanFactoryAware.class); 162 ignoreDependencyInterface(BeanClassLoaderAware.class); 163 } 164 165 /** 166 * Create a new AbstractAutowireCapableBeanFactory with the given parent. 167 * @param parentBeanFactory parent bean factory, or {@code null} if none 168 */ 169 public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) { 170 this(); 171 setParentBeanFactory(parentBeanFactory); 172 } 173 174 175 /** 176 * Set the instantiation strategy to use for creating bean instances. 177 * Default is CglibSubclassingInstantiationStrategy. 178 * @see CglibSubclassingInstantiationStrategy 179 */ 180 public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { 181 this.instantiationStrategy = instantiationStrategy; 182 } 183 184 /** 185 * Return the instantiation strategy to use for creating bean instances. 186 */ 187 protected InstantiationStrategy getInstantiationStrategy() { 188 return this.instantiationStrategy; 189 } 190 191 /** 192 * Set the ParameterNameDiscoverer to use for resolving method parameter 193 * names if needed (e.g. for constructor names). 194 * <p>Default is a {@link DefaultParameterNameDiscoverer}. 195 */ 196 public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) { 197 this.parameterNameDiscoverer = parameterNameDiscoverer; 198 } 199 200 /** 201 * Return the ParameterNameDiscoverer to use for resolving method parameter 202 * names if needed. 203 */ 204 protected ParameterNameDiscoverer getParameterNameDiscoverer() { 205 return this.parameterNameDiscoverer; 206 } 207 208 /** 209 * Set whether to allow circular references between beans - and automatically 210 * try to resolve them. 211 * <p>Note that circular reference resolution means that one of the involved beans 212 * will receive a reference to another bean that is not fully initialized yet. 213 * This can lead to subtle and not-so-subtle side effects on initialization; 214 * it does work fine for many scenarios, though. 215 * <p>Default is "true". Turn this off to throw an exception when encountering 216 * a circular reference, disallowing them completely. 217 * <p><b>NOTE:</b> It is generally recommended to not rely on circular references 218 * between your beans. Refactor your application logic to have the two beans 219 * involved delegate to a third bean that encapsulates their common logic. 220 */ 221 public void setAllowCircularReferences(boolean allowCircularReferences) { 222 this.allowCircularReferences = allowCircularReferences; 223 } 224 225 /** 226 * Set whether to allow the raw injection of a bean instance into some other 227 * bean's property, despite the injected bean eventually getting wrapped 228 * (for example, through AOP auto-proxying). 229 * <p>This will only be used as a last resort in case of a circular reference 230 * that cannot be resolved otherwise: essentially, preferring a raw instance 231 * getting injected over a failure of the entire bean wiring process. 232 * <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped 233 * raw beans injected into some of your references, which was Spring 1.2's 234 * (arguably unclean) default behavior. 235 * <p><b>NOTE:</b> It is generally recommended to not rely on circular references 236 * between your beans, in particular with auto-proxying involved. 237 * @see #setAllowCircularReferences 238 */ 239 public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) { 240 this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping; 241 } 242 243 /** 244 * Ignore the given dependency type for autowiring: 245 * for example, String. Default is none. 246 */ 247 public void ignoreDependencyType(Class<?> type) { 248 this.ignoredDependencyTypes.add(type); 249 } 250 251 /** 252 * Ignore the given dependency interface for autowiring. 253 * <p>This will typically be used by application contexts to register 254 * dependencies that are resolved in other ways, like BeanFactory through 255 * BeanFactoryAware or ApplicationContext through ApplicationContextAware. 256 * <p>By default, only the BeanFactoryAware interface is ignored. 257 * For further types to ignore, invoke this method for each type. 258 * @see org.springframework.beans.factory.BeanFactoryAware 259 * @see org.springframework.context.ApplicationContextAware 260 */ 261 public void ignoreDependencyInterface(Class<?> ifc) { 262 this.ignoredDependencyInterfaces.add(ifc); 263 } 264 265 @Override 266 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { 267 super.copyConfigurationFrom(otherFactory); 268 if (otherFactory instanceof AbstractAutowireCapableBeanFactory) { 269 AbstractAutowireCapableBeanFactory otherAutowireFactory = 270 (AbstractAutowireCapableBeanFactory) otherFactory; 271 this.instantiationStrategy = otherAutowireFactory.instantiationStrategy; 272 this.allowCircularReferences = otherAutowireFactory.allowCircularReferences; 273 this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes); 274 this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces); 275 } 276 } 277 278 279 //------------------------------------------------------------------------- 280 // Typical methods for creating and populating external bean instances 281 //------------------------------------------------------------------------- 282 283 @Override 284 @SuppressWarnings("unchecked") 285 public <T> T createBean(Class<T> beanClass) throws BeansException { 286 // Use prototype bean definition, to avoid registering bean as dependent bean. 287 RootBeanDefinition bd = new RootBeanDefinition(beanClass); 288 bd.setScope(SCOPE_PROTOTYPE); 289 bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader()); 290 return (T) createBean(beanClass.getName(), bd, null); 291 } 292 293 @Override 294 public void autowireBean(Object existingBean) { 295 // Use non-singleton bean definition, to avoid registering bean as dependent bean. 296 RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean)); 297 bd.setScope(SCOPE_PROTOTYPE); 298 bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader()); 299 BeanWrapper bw = new BeanWrapperImpl(existingBean); 300 initBeanWrapper(bw); 301 populateBean(bd.getBeanClass().getName(), bd, bw); 302 } 303 304 @Override 305 public Object configureBean(Object existingBean, String beanName) throws BeansException { 306 markBeanAsCreated(beanName); 307 BeanDefinition mbd = getMergedBeanDefinition(beanName); 308 RootBeanDefinition bd = null; 309 if (mbd instanceof RootBeanDefinition) { 310 RootBeanDefinition rbd = (RootBeanDefinition) mbd; 311 bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition()); 312 } 313 if (!mbd.isPrototype()) { 314 if (bd == null) { 315 bd = new RootBeanDefinition(mbd); 316 } 317 bd.setScope(SCOPE_PROTOTYPE); 318 bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader()); 319 } 320 BeanWrapper bw = new BeanWrapperImpl(existingBean); 321 initBeanWrapper(bw); 322 populateBean(beanName, bd, bw); 323 return initializeBean(beanName, existingBean, bd); 324 } 325 326 @Override 327 public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException { 328 return resolveDependency(descriptor, requestingBeanName, null, null); 329 } 330 331 332 //------------------------------------------------------------------------- 333 // Specialized methods for fine-grained control over the bean lifecycle 334 //------------------------------------------------------------------------- 335 336 @Override 337 public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException { 338 // Use non-singleton bean definition, to avoid registering bean as dependent bean. 339 RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); 340 bd.setScope(SCOPE_PROTOTYPE); 341 return createBean(beanClass.getName(), bd, null); 342 } 343 344 @Override 345 public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException { 346 // Use non-singleton bean definition, to avoid registering bean as dependent bean. 347 final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); 348 bd.setScope(SCOPE_PROTOTYPE); 349 if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) { 350 return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance(); 351 } 352 else { 353 Object bean; 354 final BeanFactory parent = this; 355 if (System.getSecurityManager() != null) { 356 bean = AccessController.doPrivileged(new PrivilegedAction<Object>() { 357 @Override 358 public Object run() { 359 return getInstantiationStrategy().instantiate(bd, null, parent); 360 } 361 }, getAccessControlContext()); 362 } 363 else { 364 bean = getInstantiationStrategy().instantiate(bd, null, parent); 365 } 366 populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean)); 367 return bean; 368 } 369 } 370 371 @Override 372 public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) 373 throws BeansException { 374 375 if (autowireMode == AUTOWIRE_CONSTRUCTOR) { 376 throw new IllegalArgumentException("AUTOWIRE_CONSTRUCTOR not supported for existing bean instance"); 377 } 378 // Use non-singleton bean definition, to avoid registering bean as dependent bean. 379 RootBeanDefinition bd = 380 new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck); 381 bd.setScope(SCOPE_PROTOTYPE); 382 BeanWrapper bw = new BeanWrapperImpl(existingBean); 383 initBeanWrapper(bw); 384 populateBean(bd.getBeanClass().getName(), bd, bw); 385 } 386 387 @Override 388 public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException { 389 markBeanAsCreated(beanName); 390 BeanDefinition bd = getMergedBeanDefinition(beanName); 391 BeanWrapper bw = new BeanWrapperImpl(existingBean); 392 initBeanWrapper(bw); 393 applyPropertyValues(beanName, bd, bw, bd.getPropertyValues()); 394 } 395 396 @Override 397 public Object initializeBean(Object existingBean, String beanName) { 398 return initializeBean(beanName, existingBean, null); 399 } 400 401 @Override 402 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) 403 throws BeansException { 404 405 Object result = existingBean; 406 for (BeanPostProcessor processor : getBeanPostProcessors()) { 407 result = processor.postProcessBeforeInitialization(result, beanName); 408 if (result == null) { 409 return result; 410 } 411 } 412 return result; 413 } 414 415 @Override 416 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 417 throws BeansException { 418 419 Object result = existingBean; 420 for (BeanPostProcessor processor : getBeanPostProcessors()) { 421 result = processor.postProcessAfterInitialization(result, beanName); 422 if (result == null) { 423 return result; 424 } 425 } 426 return result; 427 } 428 429 @Override 430 public void destroyBean(Object existingBean) { 431 new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy(); 432 } 433 434 435 //--------------------------------------------------------------------- 436 // Implementation of relevant AbstractBeanFactory template methods 437 //--------------------------------------------------------------------- 438 439 /** 440 * Central method of this class: creates a bean instance, 441 * populates the bean instance, applies post-processors, etc. 442 * @see #doCreateBean 443 */ 444 @Override 445 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { 446 if (logger.isDebugEnabled()) { 447 logger.debug("Creating instance of bean '" + beanName + "'"); 448 } 449 RootBeanDefinition mbdToUse = mbd; 450 451 // Make sure bean class is actually resolved at this point, and 452 // clone the bean definition in case of a dynamically resolved Class 453 // which cannot be stored in the shared merged bean definition. 454 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 455 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 456 mbdToUse = new RootBeanDefinition(mbd); 457 mbdToUse.setBeanClass(resolvedClass); 458 } 459 460 // Prepare method overrides. 461 try { 462 mbdToUse.prepareMethodOverrides(); 463 } 464 catch (BeanDefinitionValidationException ex) { 465 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 466 beanName, "Validation of method overrides failed", ex); 467 } 468 469 try { 470 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 471 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 472 if (bean != null) { 473 return bean; 474 } 475 } 476 catch (Throwable ex) { 477 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 478 "BeanPostProcessor before instantiation of bean failed", ex); 479 } 480 481 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 482 if (logger.isDebugEnabled()) { 483 logger.debug("Finished creating instance of bean '" + beanName + "'"); 484 } 485 return beanInstance; 486 } 487 488 /** 489 * Actually create the specified bean. Pre-creation processing has already happened 490 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. 491 * <p>Differentiates between default bean instantiation, use of a 492 * factory method, and autowiring a constructor. 493 * @param beanName the name of the bean 494 * @param mbd the merged bean definition for the bean 495 * @param args explicit arguments to use for constructor or factory method invocation 496 * @return a new instance of the bean 497 * @throws BeanCreationException if the bean could not be created 498 * @see #instantiateBean 499 * @see #instantiateUsingFactoryMethod 500 * @see #autowireConstructor 501 */ 502 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 503 throws BeanCreationException { 504 505 // Instantiate the bean. 506 BeanWrapper instanceWrapper = null; 507 if (mbd.isSingleton()) { 508 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 509 } 510 if (instanceWrapper == null) { 511 instanceWrapper = createBeanInstance(beanName, mbd, args); 512 } 513 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); 514 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); 515 mbd.resolvedTargetType = beanType; 516 517 // Allow post-processors to modify the merged bean definition. 518 synchronized (mbd.postProcessingLock) { 519 if (!mbd.postProcessed) { 520 try { 521 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 522 } 523 catch (Throwable ex) { 524 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 525 "Post-processing of merged bean definition failed", ex); 526 } 527 mbd.postProcessed = true; 528 } 529 } 530 531 // Eagerly cache singletons to be able to resolve circular references 532 // even when triggered by lifecycle interfaces like BeanFactoryAware. 533 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 534 isSingletonCurrentlyInCreation(beanName)); 535 if (earlySingletonExposure) { 536 if (logger.isDebugEnabled()) { 537 logger.debug("Eagerly caching bean '" + beanName + 538 "' to allow for resolving potential circular references"); 539 } 540 addSingletonFactory(beanName, new ObjectFactory<Object>() { 541 @Override 542 public Object getObject() throws BeansException { 543 return getEarlyBeanReference(beanName, mbd, bean); 544 } 545 }); 546 } 547 548 // Initialize the bean instance. 549 Object exposedObject = bean; 550 try { 551 populateBean(beanName, mbd, instanceWrapper); 552 if (exposedObject != null) { 553 exposedObject = initializeBean(beanName, exposedObject, mbd); 554 } 555 } 556 catch (Throwable ex) { 557 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { 558 throw (BeanCreationException) ex; 559 } 560 else { 561 throw new BeanCreationException( 562 mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); 563 } 564 } 565 566 if (earlySingletonExposure) { 567 Object earlySingletonReference = getSingleton(beanName, false); 568 if (earlySingletonReference != null) { 569 if (exposedObject == bean) { 570 exposedObject = earlySingletonReference; 571 } 572 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { 573 String[] dependentBeans = getDependentBeans(beanName); 574 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); 575 for (String dependentBean : dependentBeans) { 576 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 577 actualDependentBeans.add(dependentBean); 578 } 579 } 580 if (!actualDependentBeans.isEmpty()) { 581 throw new BeanCurrentlyInCreationException(beanName, 582 "Bean with name '" + beanName + "' has been injected into other beans [" + 583 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 584 "] in its raw version as part of a circular reference, but has eventually been " + 585 "wrapped. This means that said other beans do not use the final version of the " + 586 "bean. This is often the result of over-eager type matching - consider using " + 587 "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); 588 } 589 } 590 } 591 } 592 593 // Register bean as disposable. 594 try { 595 registerDisposableBeanIfNecessary(beanName, bean, mbd); 596 } 597 catch (BeanDefinitionValidationException ex) { 598 throw new BeanCreationException( 599 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); 600 } 601 602 return exposedObject; 603 } 604 605 @Override 606 protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { 607 Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch); 608 // Apply SmartInstantiationAwareBeanPostProcessors to predict the 609 // eventual type after a before-instantiation shortcut. 610 if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 611 for (BeanPostProcessor bp : getBeanPostProcessors()) { 612 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 613 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 614 Class<?> predicted = ibp.predictBeanType(targetType, beanName); 615 if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] || 616 FactoryBean.class.isAssignableFrom(predicted))) { 617 return predicted; 618 } 619 } 620 } 621 } 622 return targetType; 623 } 624 625 /** 626 * Determine the target type for the given bean definition. 627 * @param beanName the name of the bean (for error handling purposes) 628 * @param mbd the merged bean definition for the bean 629 * @param typesToMatch the types to match in case of internal type matching purposes 630 * (also signals that the returned {@code Class} will never be exposed to application code) 631 * @return the type for the bean if determinable, or {@code null} otherwise 632 */ 633 protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { 634 Class<?> targetType = mbd.getTargetType(); 635 if (targetType == null) { 636 targetType = (mbd.getFactoryMethodName() != null ? 637 getTypeForFactoryMethod(beanName, mbd, typesToMatch) : 638 resolveBeanClass(mbd, beanName, typesToMatch)); 639 if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) { 640 mbd.resolvedTargetType = targetType; 641 } 642 } 643 return targetType; 644 } 645 646 /** 647 * Determine the target type for the given bean definition which is based on 648 * a factory method. Only called if there is no singleton instance registered 649 * for the target bean already. 650 * <p>This implementation determines the type matching {@link #createBean}'s 651 * different creation strategies. As far as possible, we'll perform static 652 * type checking to avoid creation of the target bean. 653 * @param beanName the name of the bean (for error handling purposes) 654 * @param mbd the merged bean definition for the bean 655 * @param typesToMatch the types to match in case of internal type matching purposes 656 * (also signals that the returned {@code Class} will never be exposed to application code) 657 * @return the type for the bean if determinable, or {@code null} otherwise 658 * @see #createBean 659 */ 660 protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { 661 ResolvableType cachedReturnType = mbd.factoryMethodReturnType; 662 if (cachedReturnType != null) { 663 return cachedReturnType.resolve(); 664 } 665 666 Class<?> factoryClass; 667 boolean isStatic = true; 668 669 String factoryBeanName = mbd.getFactoryBeanName(); 670 if (factoryBeanName != null) { 671 if (factoryBeanName.equals(beanName)) { 672 throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, 673 "factory-bean reference points back to the same bean definition"); 674 } 675 // Check declared factory method return type on factory class. 676 factoryClass = getType(factoryBeanName); 677 isStatic = false; 678 } 679 else { 680 // Check declared factory method return type on bean class. 681 factoryClass = resolveBeanClass(mbd, beanName, typesToMatch); 682 } 683 684 if (factoryClass == null) { 685 return null; 686 } 687 factoryClass = ClassUtils.getUserClass(factoryClass); 688 689 // If all factory methods have the same return type, return that type. 690 // Can't clearly figure out exact method due to type converting / autowiring! 691 Class<?> commonType = null; 692 Method uniqueCandidate = null; 693 int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount(); 694 Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass); 695 for (Method candidate : candidates) { 696 if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) && 697 candidate.getParameterTypes().length >= minNrOfArgs) { 698 // Declared type variables to inspect? 699 if (candidate.getTypeParameters().length > 0) { 700 try { 701 // Fully resolve parameter names and argument values. 702 Class<?>[] paramTypes = candidate.getParameterTypes(); 703 String[] paramNames = null; 704 ParameterNameDiscoverer pnd = getParameterNameDiscoverer(); 705 if (pnd != null) { 706 paramNames = pnd.getParameterNames(candidate); 707 } 708 ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); 709 Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = 710 new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length); 711 Object[] args = new Object[paramTypes.length]; 712 for (int i = 0; i < args.length; i++) { 713 ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue( 714 i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders); 715 if (valueHolder == null) { 716 valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders); 717 } 718 if (valueHolder != null) { 719 args[i] = valueHolder.getValue(); 720 usedValueHolders.add(valueHolder); 721 } 722 } 723 Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( 724 candidate, args, getBeanClassLoader()); 725 if (returnType != null) { 726 uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ? 727 candidate : null); 728 commonType = ClassUtils.determineCommonAncestor(returnType, commonType); 729 if (commonType == null) { 730 // Ambiguous return types found: return null to indicate "not determinable". 731 return null; 732 } 733 } 734 } 735 catch (Throwable ex) { 736 if (logger.isDebugEnabled()) { 737 logger.debug("Failed to resolve generic return type for factory method: " + ex); 738 } 739 } 740 } 741 else { 742 uniqueCandidate = (commonType == null ? candidate : null); 743 commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType); 744 if (commonType == null) { 745 // Ambiguous return types found: return null to indicate "not determinable". 746 return null; 747 } 748 } 749 } 750 } 751 752 if (commonType == null) { 753 return null; 754 } 755 // Common return type found: all factory methods return same type. For a non-parameterized 756 // unique candidate, cache the full type declaration context of the target factory method. 757 cachedReturnType = (uniqueCandidate != null ? 758 ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType)); 759 mbd.factoryMethodReturnType = cachedReturnType; 760 return cachedReturnType.resolve(); 761 } 762 763 /** 764 * This implementation attempts to query the FactoryBean's generic parameter metadata 765 * if present to determine the object type. If not present, i.e. the FactoryBean is 766 * declared as a raw type, checks the FactoryBean's {@code getObjectType} method 767 * on a plain instance of the FactoryBean, without bean properties applied yet. 768 * If this doesn't return a type yet, a full creation of the FactoryBean is 769 * used as fallback (through delegation to the superclass's implementation). 770 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton 771 * FactoryBean. If the FactoryBean instance itself is not kept as singleton, 772 * it will be fully created to check the type of its exposed object. 773 */ 774 @Override 775 protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) { 776 String factoryBeanName = mbd.getFactoryBeanName(); 777 String factoryMethodName = mbd.getFactoryMethodName(); 778 779 if (factoryBeanName != null) { 780 if (factoryMethodName != null) { 781 // Try to obtain the FactoryBean's object type from its factory method declaration 782 // without instantiating the containing bean at all. 783 BeanDefinition fbDef = getBeanDefinition(factoryBeanName); 784 if (fbDef instanceof AbstractBeanDefinition) { 785 AbstractBeanDefinition afbDef = (AbstractBeanDefinition) fbDef; 786 if (afbDef.hasBeanClass()) { 787 Class<?> result = getTypeForFactoryBeanFromMethod(afbDef.getBeanClass(), factoryMethodName); 788 if (result != null) { 789 return result; 790 } 791 } 792 } 793 } 794 // If not resolvable above and the referenced factory bean doesn't exist yet, 795 // exit here - we don't want to force the creation of another bean just to 796 // obtain a FactoryBean's object type... 797 if (!isBeanEligibleForMetadataCaching(factoryBeanName)) { 798 return null; 799 } 800 } 801 802 // Let's obtain a shortcut instance for an early getObjectType() call... 803 FactoryBean<?> fb = (mbd.isSingleton() ? 804 getSingletonFactoryBeanForTypeCheck(beanName, mbd) : 805 getNonSingletonFactoryBeanForTypeCheck(beanName, mbd)); 806 807 if (fb != null) { 808 // Try to obtain the FactoryBean's object type from this early stage of the instance. 809 Class<?> result = getTypeForFactoryBean(fb); 810 if (result != null) { 811 return result; 812 } 813 else { 814 // No type found for shortcut FactoryBean instance: 815 // fall back to full creation of the FactoryBean instance. 816 return super.getTypeForFactoryBean(beanName, mbd); 817 } 818 } 819 820 if (factoryBeanName == null && mbd.hasBeanClass()) { 821 // No early bean instantiation possible: determine FactoryBean's type from 822 // static factory method signature or from class inheritance hierarchy... 823 if (factoryMethodName != null) { 824 return getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName); 825 } 826 else { 827 return GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class); 828 } 829 } 830 831 return null; 832 } 833 834 /** 835 * Introspect the factory method signatures on the given bean class, 836 * trying to find a common {@code FactoryBean} object type declared there. 837 * @param beanClass the bean class to find the factory method on 838 * @param factoryMethodName the name of the factory method 839 * @return the common {@code FactoryBean} object type, or {@code null} if none 840 */ 841 private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) { 842 class Holder { Class<?> value = null; } 843 final Holder objectType = new Holder(); 844 845 // CGLIB subclass methods hide generic parameters; look at the original user class. 846 Class<?> fbClass = ClassUtils.getUserClass(beanClass); 847 848 // Find the given factory method, taking into account that in the case of 849 // @Bean methods, there may be parameters present. 850 ReflectionUtils.doWithMethods(fbClass, 851 new ReflectionUtils.MethodCallback() { 852 @Override 853 public void doWith(Method method) { 854 if (method.getName().equals(factoryMethodName) && 855 FactoryBean.class.isAssignableFrom(method.getReturnType())) { 856 Class<?> currentType = GenericTypeResolver.resolveReturnTypeArgument( 857 method, FactoryBean.class); 858 if (currentType != null) { 859 objectType.value = ClassUtils.determineCommonAncestor(currentType, objectType.value); 860 } 861 } 862 } 863 }); 864 865 return (objectType.value != null && Object.class != objectType.value ? objectType.value : null); 866 } 867 868 /** 869 * Obtain a reference for early access to the specified bean, 870 * typically for the purpose of resolving a circular reference. 871 * @param beanName the name of the bean (for error handling purposes) 872 * @param mbd the merged bean definition for the bean 873 * @param bean the raw bean instance 874 * @return the object to expose as bean reference 875 */ 876 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { 877 Object exposedObject = bean; 878 if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 879 for (BeanPostProcessor bp : getBeanPostProcessors()) { 880 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 881 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 882 exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); 883 if (exposedObject == null) { 884 return null; 885 } 886 } 887 } 888 } 889 return exposedObject; 890 } 891 892 893 //--------------------------------------------------------------------- 894 // Implementation methods 895 //--------------------------------------------------------------------- 896 897 /** 898 * Obtain a "shortcut" singleton FactoryBean instance to use for a 899 * {@code getObjectType()} call, without full initialization of the FactoryBean. 900 * @param beanName the name of the bean 901 * @param mbd the bean definition for the bean 902 * @return the FactoryBean instance, or {@code null} to indicate 903 * that we couldn't obtain a shortcut FactoryBean instance 904 */ 905 private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) { 906 synchronized (getSingletonMutex()) { 907 BeanWrapper bw = this.factoryBeanInstanceCache.get(beanName); 908 if (bw != null) { 909 return (FactoryBean<?>) bw.getWrappedInstance(); 910 } 911 Object beanInstance = getSingleton(beanName, false); 912 if (beanInstance instanceof FactoryBean) { 913 return (FactoryBean<?>) beanInstance; 914 } 915 if (isSingletonCurrentlyInCreation(beanName) || 916 (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) { 917 return null; 918 } 919 920 Object instance; 921 try { 922 // Mark this bean as currently in creation, even if just partially. 923 beforeSingletonCreation(beanName); 924 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 925 instance = resolveBeforeInstantiation(beanName, mbd); 926 if (instance == null) { 927 bw = createBeanInstance(beanName, mbd, null); 928 instance = bw.getWrappedInstance(); 929 } 930 } 931 finally { 932 // Finished partial creation of this bean. 933 afterSingletonCreation(beanName); 934 } 935 936 FactoryBean<?> fb = getFactoryBean(beanName, instance); 937 if (bw != null) { 938 this.factoryBeanInstanceCache.put(beanName, bw); 939 } 940 return fb; 941 } 942 } 943 944 /** 945 * Obtain a "shortcut" non-singleton FactoryBean instance to use for a 946 * {@code getObjectType()} call, without full initialization of the FactoryBean. 947 * @param beanName the name of the bean 948 * @param mbd the bean definition for the bean 949 * @return the FactoryBean instance, or {@code null} to indicate 950 * that we couldn't obtain a shortcut FactoryBean instance 951 */ 952 private FactoryBean<?> getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) { 953 if (isPrototypeCurrentlyInCreation(beanName)) { 954 return null; 955 } 956 957 Object instance; 958 try { 959 // Mark this bean as currently in creation, even if just partially. 960 beforePrototypeCreation(beanName); 961 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 962 instance = resolveBeforeInstantiation(beanName, mbd); 963 if (instance == null) { 964 BeanWrapper bw = createBeanInstance(beanName, mbd, null); 965 instance = bw.getWrappedInstance(); 966 } 967 } 968 catch (BeanCreationException ex) { 969 // Can only happen when getting a FactoryBean. 970 if (logger.isDebugEnabled()) { 971 logger.debug("Bean creation exception on non-singleton FactoryBean type check: " + ex); 972 } 973 onSuppressedException(ex); 974 return null; 975 } 976 finally { 977 // Finished partial creation of this bean. 978 afterPrototypeCreation(beanName); 979 } 980 981 return getFactoryBean(beanName, instance); 982 } 983 984 /** 985 * Apply MergedBeanDefinitionPostProcessors to the specified bean definition, 986 * invoking their {@code postProcessMergedBeanDefinition} methods. 987 * @param mbd the merged bean definition for the bean 988 * @param beanType the actual type of the managed bean instance 989 * @param beanName the name of the bean 990 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 991 */ 992 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { 993 for (BeanPostProcessor bp : getBeanPostProcessors()) { 994 if (bp instanceof MergedBeanDefinitionPostProcessor) { 995 MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; 996 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); 997 } 998 } 999 } 1000 1001 /** 1002 * Apply before-instantiation post-processors, resolving whether there is a 1003 * before-instantiation shortcut for the specified bean. 1004 * @param beanName the name of the bean 1005 * @param mbd the bean definition for the bean 1006 * @return the shortcut-determined bean instance, or {@code null} if none 1007 */ 1008 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { 1009 Object bean = null; 1010 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 1011 // Make sure bean class is actually resolved at this point. 1012 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 1013 Class<?> targetType = determineTargetType(beanName, mbd); 1014 if (targetType != null) { 1015 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 1016 if (bean != null) { 1017 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 1018 } 1019 } 1020 } 1021 mbd.beforeInstantiationResolved = (bean != null); 1022 } 1023 return bean; 1024 } 1025 1026 /** 1027 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition 1028 * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods. 1029 * <p>Any returned object will be used as the bean instead of actually instantiating 1030 * the target bean. A {@code null} return value from the post-processor will 1031 * result in the target bean being instantiated. 1032 * @param beanClass the class of the bean to be instantiated 1033 * @param beanName the name of the bean 1034 * @return the bean object to use instead of a default instance of the target bean, or {@code null} 1035 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 1036 */ 1037 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { 1038 for (BeanPostProcessor bp : getBeanPostProcessors()) { 1039 if (bp instanceof InstantiationAwareBeanPostProcessor) { 1040 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 1041 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); 1042 if (result != null) { 1043 return result; 1044 } 1045 } 1046 } 1047 return null; 1048 } 1049 1050 /** 1051 * Create a new instance for the specified bean, using an appropriate instantiation strategy: 1052 * factory method, constructor autowiring, or simple instantiation. 1053 * @param beanName the name of the bean 1054 * @param mbd the bean definition for the bean 1055 * @param args explicit arguments to use for constructor or factory method invocation 1056 * @return a BeanWrapper for the new instance 1057 * @see #instantiateUsingFactoryMethod 1058 * @see #autowireConstructor 1059 * @see #instantiateBean 1060 */ 1061 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { 1062 // Make sure bean class is actually resolved at this point. 1063 Class<?> beanClass = resolveBeanClass(mbd, beanName); 1064 1065 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { 1066 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 1067 "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); 1068 } 1069 1070 if (mbd.getFactoryMethodName() != null) { 1071 return instantiateUsingFactoryMethod(beanName, mbd, args); 1072 } 1073 1074 // Shortcut when re-creating the same bean... 1075 boolean resolved = false; 1076 boolean autowireNecessary = false; 1077 if (args == null) { 1078 synchronized (mbd.constructorArgumentLock) { 1079 if (mbd.resolvedConstructorOrFactoryMethod != null) { 1080 resolved = true; 1081 autowireNecessary = mbd.constructorArgumentsResolved; 1082 } 1083 } 1084 } 1085 if (resolved) { 1086 if (autowireNecessary) { 1087 return autowireConstructor(beanName, mbd, null, null); 1088 } 1089 else { 1090 return instantiateBean(beanName, mbd); 1091 } 1092 } 1093 1094 // Candidate constructors for autowiring? 1095 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 1096 if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || 1097 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 1098 return autowireConstructor(beanName, mbd, ctors, args); 1099 } 1100 1101 // No special handling: simply use no-arg constructor. 1102 return instantiateBean(beanName, mbd); 1103 } 1104 1105 /** 1106 * Determine candidate constructors to use for the given bean, checking all registered 1107 * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}. 1108 * @param beanClass the raw class of the bean 1109 * @param beanName the name of the bean 1110 * @return the candidate constructors, or {@code null} if none specified 1111 * @throws org.springframework.beans.BeansException in case of errors 1112 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 1113 */ 1114 protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) 1115 throws BeansException { 1116 1117 if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { 1118 for (BeanPostProcessor bp : getBeanPostProcessors()) { 1119 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 1120 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 1121 Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); 1122 if (ctors != null) { 1123 return ctors; 1124 } 1125 } 1126 } 1127 } 1128 return null; 1129 } 1130 1131 /** 1132 * Instantiate the given bean using its default constructor. 1133 * @param beanName the name of the bean 1134 * @param mbd the bean definition for the bean 1135 * @return a BeanWrapper for the new instance 1136 */ 1137 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { 1138 try { 1139 Object beanInstance; 1140 final BeanFactory parent = this; 1141 if (System.getSecurityManager() != null) { 1142 beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { 1143 @Override 1144 public Object run() { 1145 return getInstantiationStrategy().instantiate(mbd, beanName, parent); 1146 } 1147 }, getAccessControlContext()); 1148 } 1149 else { 1150 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); 1151 } 1152 BeanWrapper bw = new BeanWrapperImpl(beanInstance); 1153 initBeanWrapper(bw); 1154 return bw; 1155 } 1156 catch (Throwable ex) { 1157 throw new BeanCreationException( 1158 mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); 1159 } 1160 } 1161 1162 /** 1163 * Instantiate the bean using a named factory method. The method may be static, if the 1164 * mbd parameter specifies a class, rather than a factoryBean, or an instance variable 1165 * on a factory object itself configured using Dependency Injection. 1166 * @param beanName the name of the bean 1167 * @param mbd the bean definition for the bean 1168 * @param explicitArgs argument values passed in programmatically via the getBean method, 1169 * or {@code null} if none (-> use constructor argument values from bean definition) 1170 * @return a BeanWrapper for the new instance 1171 * @see #getBean(String, Object[]) 1172 */ 1173 protected BeanWrapper instantiateUsingFactoryMethod( 1174 String beanName, RootBeanDefinition mbd, Object[] explicitArgs) { 1175 1176 return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); 1177 } 1178 1179 /** 1180 * "autowire constructor" (with constructor arguments by type) behavior. 1181 * Also applied if explicit constructor argument values are specified, 1182 * matching all remaining arguments with beans from the bean factory. 1183 * <p>This corresponds to constructor injection: In this mode, a Spring 1184 * bean factory is able to host components that expect constructor-based 1185 * dependency resolution. 1186 * @param beanName the name of the bean 1187 * @param mbd the bean definition for the bean 1188 * @param ctors the chosen candidate constructors 1189 * @param explicitArgs argument values passed in programmatically via the getBean method, 1190 * or {@code null} if none (-> use constructor argument values from bean definition) 1191 * @return a BeanWrapper for the new instance 1192 */ 1193 protected BeanWrapper autowireConstructor( 1194 String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) { 1195 1196 return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); 1197 } 1198 1199 /** 1200 * Populate the bean instance in the given BeanWrapper with the property values 1201 * from the bean definition. 1202 * @param beanName the name of the bean 1203 * @param mbd the bean definition for the bean 1204 * @param bw the BeanWrapper with bean instance 1205 */ 1206 protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { 1207 PropertyValues pvs = mbd.getPropertyValues(); 1208 1209 if (bw == null) { 1210 if (!pvs.isEmpty()) { 1211 throw new BeanCreationException( 1212 mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); 1213 } 1214 else { 1215 // Skip property population phase for null instance. 1216 return; 1217 } 1218 } 1219 1220 // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the 1221 // state of the bean before properties are set. This can be used, for example, 1222 // to support styles of field injection. 1223 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 1224 for (BeanPostProcessor bp : getBeanPostProcessors()) { 1225 if (bp instanceof InstantiationAwareBeanPostProcessor) { 1226 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 1227 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 1228 return; 1229 } 1230 } 1231 } 1232 } 1233 1234 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 1235 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 1236 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 1237 // Add property values based on autowire by name if applicable. 1238 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { 1239 autowireByName(beanName, mbd, bw, newPvs); 1240 } 1241 // Add property values based on autowire by type if applicable. 1242 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 1243 autowireByType(beanName, mbd, bw, newPvs); 1244 } 1245 pvs = newPvs; 1246 } 1247 1248 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); 1249 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); 1250 1251 if (hasInstAwareBpps || needsDepCheck) { 1252 PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); 1253 if (hasInstAwareBpps) { 1254 for (BeanPostProcessor bp : getBeanPostProcessors()) { 1255 if (bp instanceof InstantiationAwareBeanPostProcessor) { 1256 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 1257 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 1258 if (pvs == null) { 1259 return; 1260 } 1261 } 1262 } 1263 } 1264 if (needsDepCheck) { 1265 checkDependencies(beanName, mbd, filteredPds, pvs); 1266 } 1267 } 1268 1269 applyPropertyValues(beanName, mbd, bw, pvs); 1270 } 1271 1272 /** 1273 * Fill in any missing property values with references to 1274 * other beans in this factory if autowire is set to "byName". 1275 * @param beanName the name of the bean we're wiring up. 1276 * Useful for debugging messages; not used functionally. 1277 * @param mbd bean definition to update through autowiring 1278 * @param bw the BeanWrapper from which we can obtain information about the bean 1279 * @param pvs the PropertyValues to register wired objects with 1280 */ 1281 protected void autowireByName( 1282 String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { 1283 1284 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); 1285 for (String propertyName : propertyNames) { 1286 if (containsBean(propertyName)) { 1287 Object bean = getBean(propertyName); 1288 pvs.add(propertyName, bean); 1289 registerDependentBean(propertyName, beanName); 1290 if (logger.isDebugEnabled()) { 1291 logger.debug("Added autowiring by name from bean name '" + beanName + 1292 "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); 1293 } 1294 } 1295 else { 1296 if (logger.isTraceEnabled()) { 1297 logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + 1298 "' by name: no matching bean found"); 1299 } 1300 } 1301 } 1302 } 1303 1304 /** 1305 * Abstract method defining "autowire by type" (bean properties by type) behavior. 1306 * <p>This is like PicoContainer default, in which there must be exactly one bean 1307 * of the property type in the bean factory. This makes bean factories simple to 1308 * configure for small namespaces, but doesn't work as well as standard Spring 1309 * behavior for bigger applications. 1310 * @param beanName the name of the bean to autowire by type 1311 * @param mbd the merged bean definition to update through autowiring 1312 * @param bw the BeanWrapper from which we can obtain information about the bean 1313 * @param pvs the PropertyValues to register wired objects with 1314 */ 1315 protected void autowireByType( 1316 String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { 1317 1318 TypeConverter converter = getCustomTypeConverter(); 1319 if (converter == null) { 1320 converter = bw; 1321 } 1322 1323 Set<String> autowiredBeanNames = new LinkedHashSet<String>(4); 1324 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); 1325 for (String propertyName : propertyNames) { 1326 try { 1327 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); 1328 // Don't try autowiring by type for type Object: never makes sense, 1329 // even if it technically is a unsatisfied, non-simple property. 1330 if (Object.class != pd.getPropertyType()) { 1331 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); 1332 // Do not allow eager init for type matching in case of a prioritized post-processor. 1333 boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass()); 1334 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); 1335 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); 1336 if (autowiredArgument != null) { 1337 pvs.add(propertyName, autowiredArgument); 1338 } 1339 for (String autowiredBeanName : autowiredBeanNames) { 1340 registerDependentBean(autowiredBeanName, beanName); 1341 if (logger.isDebugEnabled()) { 1342 logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + 1343 propertyName + "' to bean named '" + autowiredBeanName + "'"); 1344 } 1345 } 1346 autowiredBeanNames.clear(); 1347 } 1348 } 1349 catch (BeansException ex) { 1350 throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); 1351 } 1352 } 1353 } 1354 1355 1356 /** 1357 * Return an array of non-simple bean properties that are unsatisfied. 1358 * These are probably unsatisfied references to other beans in the 1359 * factory. Does not include simple properties like primitives or Strings. 1360 * @param mbd the merged bean definition the bean was created with 1361 * @param bw the BeanWrapper the bean was created with 1362 * @return an array of bean property names 1363 * @see org.springframework.beans.BeanUtils#isSimpleProperty 1364 */ 1365 protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { 1366 Set<String> result = new TreeSet<String>(); 1367 PropertyValues pvs = mbd.getPropertyValues(); 1368 PropertyDescriptor[] pds = bw.getPropertyDescriptors(); 1369 for (PropertyDescriptor pd : pds) { 1370 if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) && 1371 !BeanUtils.isSimpleProperty(pd.getPropertyType())) { 1372 result.add(pd.getName()); 1373 } 1374 } 1375 return StringUtils.toStringArray(result); 1376 } 1377 1378 /** 1379 * Extract a filtered set of PropertyDescriptors from the given BeanWrapper, 1380 * excluding ignored dependency types or properties defined on ignored dependency interfaces. 1381 * @param bw the BeanWrapper the bean was created with 1382 * @param cache whether to cache filtered PropertyDescriptors for the given bean Class 1383 * @return the filtered PropertyDescriptors 1384 * @see #isExcludedFromDependencyCheck 1385 * @see #filterPropertyDescriptorsForDependencyCheck(org.springframework.beans.BeanWrapper) 1386 */ 1387 protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw, boolean cache) { 1388 PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass()); 1389 if (filtered == null) { 1390 filtered = filterPropertyDescriptorsForDependencyCheck(bw); 1391 if (cache) { 1392 PropertyDescriptor[] existing = 1393 this.filteredPropertyDescriptorsCache.putIfAbsent(bw.getWrappedClass(), filtered); 1394 if (existing != null) { 1395 filtered = existing; 1396 } 1397 } 1398 } 1399 return filtered; 1400 } 1401 1402 /** 1403 * Extract a filtered set of PropertyDescriptors from the given BeanWrapper, 1404 * excluding ignored dependency types or properties defined on ignored dependency interfaces. 1405 * @param bw the BeanWrapper the bean was created with 1406 * @return the filtered PropertyDescriptors 1407 * @see #isExcludedFromDependencyCheck 1408 */ 1409 protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) { 1410 List<PropertyDescriptor> pds = 1411 new ArrayList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors())); 1412 for (Iterator<PropertyDescriptor> it = pds.iterator(); it.hasNext();) { 1413 PropertyDescriptor pd = it.next(); 1414 if (isExcludedFromDependencyCheck(pd)) { 1415 it.remove(); 1416 } 1417 } 1418 return pds.toArray(new PropertyDescriptor[pds.size()]); 1419 } 1420 1421 /** 1422 * Determine whether the given bean property is excluded from dependency checks. 1423 * <p>This implementation excludes properties defined by CGLIB and 1424 * properties whose type matches an ignored dependency type or which 1425 * are defined by an ignored dependency interface. 1426 * @param pd the PropertyDescriptor of the bean property 1427 * @return whether the bean property is excluded 1428 * @see #ignoreDependencyType(Class) 1429 * @see #ignoreDependencyInterface(Class) 1430 */ 1431 protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) { 1432 return (AutowireUtils.isExcludedFromDependencyCheck(pd) || 1433 this.ignoredDependencyTypes.contains(pd.getPropertyType()) || 1434 AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces)); 1435 } 1436 1437 /** 1438 * Perform a dependency check that all properties exposed have been set, 1439 * if desired. Dependency checks can be objects (collaborating beans), 1440 * simple (primitives and String), or all (both). 1441 * @param beanName the name of the bean 1442 * @param mbd the merged bean definition the bean was created with 1443 * @param pds the relevant property descriptors for the target bean 1444 * @param pvs the property values to be applied to the bean 1445 * @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor) 1446 */ 1447 protected void checkDependencies( 1448 String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs) 1449 throws UnsatisfiedDependencyException { 1450 1451 int dependencyCheck = mbd.getDependencyCheck(); 1452 for (PropertyDescriptor pd : pds) { 1453 if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) { 1454 boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType()); 1455 boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) || 1456 (isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) || 1457 (!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS); 1458 if (unsatisfied) { 1459 throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(), 1460 "Set this property value or disable dependency checking for this bean."); 1461 } 1462 } 1463 } 1464 } 1465 1466 /** 1467 * Apply the given property values, resolving any runtime references 1468 * to other beans in this bean factory. Must use deep copy, so we 1469 * don't permanently modify this property. 1470 * @param beanName the bean name passed for better exception information 1471 * @param mbd the merged bean definition 1472 * @param bw the BeanWrapper wrapping the target object 1473 * @param pvs the new property values 1474 */ 1475 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { 1476 if (pvs == null || pvs.isEmpty()) { 1477 return; 1478 } 1479 1480 if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { 1481 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); 1482 } 1483 1484 MutablePropertyValues mpvs = null; 1485 List<PropertyValue> original; 1486 1487 if (pvs instanceof MutablePropertyValues) { 1488 mpvs = (MutablePropertyValues) pvs; 1489 if (mpvs.isConverted()) { 1490 // Shortcut: use the pre-converted values as-is. 1491 try { 1492 bw.setPropertyValues(mpvs); 1493 return; 1494 } 1495 catch (BeansException ex) { 1496 throw new BeanCreationException( 1497 mbd.getResourceDescription(), beanName, "Error setting property values", ex); 1498 } 1499 } 1500 original = mpvs.getPropertyValueList(); 1501 } 1502 else { 1503 original = Arrays.asList(pvs.getPropertyValues()); 1504 } 1505 1506 TypeConverter converter = getCustomTypeConverter(); 1507 if (converter == null) { 1508 converter = bw; 1509 } 1510 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); 1511 1512 // Create a deep copy, resolving any references for values. 1513 List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); 1514 boolean resolveNecessary = false; 1515 for (PropertyValue pv : original) { 1516 if (pv.isConverted()) { 1517 deepCopy.add(pv); 1518 } 1519 else { 1520 String propertyName = pv.getName(); 1521 Object originalValue = pv.getValue(); 1522 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); 1523 Object convertedValue = resolvedValue; 1524 boolean convertible = bw.isWritableProperty(propertyName) && 1525 !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); 1526 if (convertible) { 1527 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); 1528 } 1529 // Possibly store converted value in merged bean definition, 1530 // in order to avoid re-conversion for every created bean instance. 1531 if (resolvedValue == originalValue) { 1532 if (convertible) { 1533 pv.setConvertedValue(convertedValue); 1534 } 1535 deepCopy.add(pv); 1536 } 1537 else if (convertible && originalValue instanceof TypedStringValue && 1538 !((TypedStringValue) originalValue).isDynamic() && 1539 !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { 1540 pv.setConvertedValue(convertedValue); 1541 deepCopy.add(pv); 1542 } 1543 else { 1544 resolveNecessary = true; 1545 deepCopy.add(new PropertyValue(pv, convertedValue)); 1546 } 1547 } 1548 } 1549 if (mpvs != null && !resolveNecessary) { 1550 mpvs.setConverted(); 1551 } 1552 1553 // Set our (possibly massaged) deep copy. 1554 try { 1555 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); 1556 } 1557 catch (BeansException ex) { 1558 throw new BeanCreationException( 1559 mbd.getResourceDescription(), beanName, "Error setting property values", ex); 1560 } 1561 } 1562 1563 /** 1564 * Convert the given value for the specified target property. 1565 */ 1566 private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) { 1567 if (converter instanceof BeanWrapperImpl) { 1568 return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName); 1569 } 1570 else { 1571 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); 1572 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); 1573 return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam); 1574 } 1575 } 1576 1577 1578 /** 1579 * Initialize the given bean instance, applying factory callbacks 1580 * as well as init methods and bean post processors. 1581 * <p>Called from {@link #createBean} for traditionally defined beans, 1582 * and from {@link #initializeBean} for existing bean instances. 1583 * @param beanName the bean name in the factory (for debugging purposes) 1584 * @param bean the new bean instance we may need to initialize 1585 * @param mbd the bean definition that the bean was created with 1586 * (can also be {@code null}, if given an existing bean instance) 1587 * @return the initialized bean instance (potentially wrapped) 1588 * @see BeanNameAware 1589 * @see BeanClassLoaderAware 1590 * @see BeanFactoryAware 1591 * @see #applyBeanPostProcessorsBeforeInitialization 1592 * @see #invokeInitMethods 1593 * @see #applyBeanPostProcessorsAfterInitialization 1594 */ 1595 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { 1596 if (System.getSecurityManager() != null) { 1597 AccessController.doPrivileged(new PrivilegedAction<Object>() { 1598 @Override 1599 public Object run() { 1600 invokeAwareMethods(beanName, bean); 1601 return null; 1602 } 1603 }, getAccessControlContext()); 1604 } 1605 else { 1606 invokeAwareMethods(beanName, bean); 1607 } 1608 1609 Object wrappedBean = bean; 1610 if (mbd == null || !mbd.isSynthetic()) { 1611 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 1612 } 1613 1614 try { 1615 invokeInitMethods(beanName, wrappedBean, mbd); 1616 } 1617 catch (Throwable ex) { 1618 throw new BeanCreationException( 1619 (mbd != null ? mbd.getResourceDescription() : null), 1620 beanName, "Invocation of init method failed", ex); 1621 } 1622 if (mbd == null || !mbd.isSynthetic()) { 1623 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 1624 } 1625 return wrappedBean; 1626 } 1627 1628 private void invokeAwareMethods(final String beanName, final Object bean) { 1629 if (bean instanceof Aware) { 1630 if (bean instanceof BeanNameAware) { 1631 ((BeanNameAware) bean).setBeanName(beanName); 1632 } 1633 if (bean instanceof BeanClassLoaderAware) { 1634 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); 1635 } 1636 if (bean instanceof BeanFactoryAware) { 1637 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); 1638 } 1639 } 1640 } 1641 1642 /** 1643 * Give a bean a chance to react now all its properties are set, 1644 * and a chance to know about its owning bean factory (this object). 1645 * This means checking whether the bean implements InitializingBean or defines 1646 * a custom init method, and invoking the necessary callback(s) if it does. 1647 * @param beanName the bean name in the factory (for debugging purposes) 1648 * @param bean the new bean instance we may need to initialize 1649 * @param mbd the merged bean definition that the bean was created with 1650 * (can also be {@code null}, if given an existing bean instance) 1651 * @throws Throwable if thrown by init methods or by the invocation process 1652 * @see #invokeCustomInitMethod 1653 */ 1654 protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) 1655 throws Throwable { 1656 1657 boolean isInitializingBean = (bean instanceof InitializingBean); 1658 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { 1659 if (logger.isDebugEnabled()) { 1660 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); 1661 } 1662 if (System.getSecurityManager() != null) { 1663 try { 1664 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 1665 @Override 1666 public Object run() throws Exception { 1667 ((InitializingBean) bean).afterPropertiesSet(); 1668 return null; 1669 } 1670 }, getAccessControlContext()); 1671 } 1672 catch (PrivilegedActionException pae) { 1673 throw pae.getException(); 1674 } 1675 } 1676 else { 1677 ((InitializingBean) bean).afterPropertiesSet(); 1678 } 1679 } 1680 1681 if (mbd != null) { 1682 String initMethodName = mbd.getInitMethodName(); 1683 if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && 1684 !mbd.isExternallyManagedInitMethod(initMethodName)) { 1685 invokeCustomInitMethod(beanName, bean, mbd); 1686 } 1687 } 1688 } 1689 1690 /** 1691 * Invoke the specified custom init method on the given bean. 1692 * Called by invokeInitMethods. 1693 * <p>Can be overridden in subclasses for custom resolution of init 1694 * methods with arguments. 1695 * @see #invokeInitMethods 1696 */ 1697 protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) 1698 throws Throwable { 1699 1700 String initMethodName = mbd.getInitMethodName(); 1701 final Method initMethod = (mbd.isNonPublicAccessAllowed() ? 1702 BeanUtils.findMethod(bean.getClass(), initMethodName) : 1703 ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName)); 1704 if (initMethod == null) { 1705 if (mbd.isEnforceInitMethod()) { 1706 throw new BeanDefinitionValidationException("Couldn't find an init method named '" + 1707 initMethodName + "' on bean with name '" + beanName + "'"); 1708 } 1709 else { 1710 if (logger.isDebugEnabled()) { 1711 logger.debug("No default init method named '" + initMethodName + 1712 "' found on bean with name '" + beanName + "'"); 1713 } 1714 // Ignore non-existent default lifecycle methods. 1715 return; 1716 } 1717 } 1718 1719 if (logger.isDebugEnabled()) { 1720 logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'"); 1721 } 1722 1723 if (System.getSecurityManager() != null) { 1724 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 1725 @Override 1726 public Object run() throws Exception { 1727 ReflectionUtils.makeAccessible(initMethod); 1728 return null; 1729 } 1730 }); 1731 try { 1732 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 1733 @Override 1734 public Object run() throws Exception { 1735 initMethod.invoke(bean); 1736 return null; 1737 } 1738 }, getAccessControlContext()); 1739 } 1740 catch (PrivilegedActionException pae) { 1741 InvocationTargetException ex = (InvocationTargetException) pae.getException(); 1742 throw ex.getTargetException(); 1743 } 1744 } 1745 else { 1746 try { 1747 ReflectionUtils.makeAccessible(initMethod); 1748 initMethod.invoke(bean); 1749 } 1750 catch (InvocationTargetException ex) { 1751 throw ex.getTargetException(); 1752 } 1753 } 1754 } 1755 1756 1757 /** 1758 * Applies the {@code postProcessAfterInitialization} callback of all 1759 * registered BeanPostProcessors, giving them a chance to post-process the 1760 * object obtained from FactoryBeans (for example, to auto-proxy them). 1761 * @see #applyBeanPostProcessorsAfterInitialization 1762 */ 1763 @Override 1764 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { 1765 return applyBeanPostProcessorsAfterInitialization(object, beanName); 1766 } 1767 1768 /** 1769 * Overridden to clear FactoryBean instance cache as well. 1770 */ 1771 @Override 1772 protected void removeSingleton(String beanName) { 1773 synchronized (getSingletonMutex()) { 1774 super.removeSingleton(beanName); 1775 this.factoryBeanInstanceCache.remove(beanName); 1776 } 1777 } 1778 1779 /** 1780 * Overridden to clear FactoryBean instance cache as well. 1781 */ 1782 @Override 1783 protected void clearSingletonCache() { 1784 synchronized (getSingletonMutex()) { 1785 super.clearSingletonCache(); 1786 this.factoryBeanInstanceCache.clear(); 1787 } 1788 } 1789 1790 1791 /** 1792 * Special DependencyDescriptor variant for Spring's good old autowire="byType" mode. 1793 * Always optional; never considering the parameter name for choosing a primary candidate. 1794 */ 1795 @SuppressWarnings("serial") 1796 private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor { 1797 1798 public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) { 1799 super(methodParameter, false, eager); 1800 } 1801 1802 @Override 1803 public String getDependencyName() { 1804 return null; 1805 } 1806 } 1807 1808}