Sprign源码——BeanFactory 加载bean

BeanFactory getBean(String)

  
  
  1. /**
  2. * Return an instance, which may be shared or independent, of the specified bean.
  3. * <p>This method allows a Spring BeanFactory to be used as a replacement for the
  4. * Singleton or Prototype design pattern. Callers may retain references to
  5. * returned objects in the case of Singleton beans.
  6. * <p>Translates aliases back to the corresponding canonical bean name.
  7. * Will ask the parent factory if the bean cannot be found in this factory instance.
  8. * @param name the name of the bean to retrieve
  9. * @return an instance of the bean
  10. * @throws NoSuchBeanDefinitionException if there is no bean definition
  11. * with the specified name
  12. * @throws BeansException if the bean could not be obtained
  13. */
  14. Object getBean(String name) throws BeansException;
在BeanFactory接口中,对getBean的定义。最终的实现在AbstractBeanFactory中。
   
   
  1. public Object getBean(String name) throws BeansException {
  2. return doGetBean(name, null, null, false);
  3. }
最终的实现
   
   
  1. /**
  2. * Return an instance, which may be shared or independent, of the specified bean.
  3. * @param name the name of the bean to retrieve
  4. * @param requiredType the required type of the bean to retrieve
  5. * @param args arguments to use if creating a prototype using explicit arguments to a
  6. * static factory method. It is invalid to use a non-null args value in any other case.
  7. * @param typeCheckOnly whether the instance is obtained for a type check,
  8. * not for actual use
  9. * @return an instance of the bean
  10. * @throws BeansException if the bean could not be created
  11. */
  12. @SuppressWarnings("unchecked")
  13. protected <T> T doGetBean(
  14. final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
  15. throws BeansException {
  16. final String beanName = transformedBeanName(name);
  17. Object bean;
  18. // Eagerly check singleton cache for manually registered singletons.
  19. Object sharedInstance = getSingleton(beanName);
  20. if (sharedInstance != null && args == null) {
  21. if (logger.isDebugEnabled()) {
  22. if (isSingletonCurrentlyInCreation(beanName)) {
  23. logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  24. "' that is not fully initialized yet - a consequence of a circular reference");
  25. }
  26. else {
  27. logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  28. }
  29. }
  30. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  31. }
  32. else {
  33. // Fail if we're already creating this bean instance:
  34. // We're assumably within a circular reference.
  35. if (isPrototypeCurrentlyInCreation(beanName)) {
  36. throw new BeanCurrentlyInCreationException(beanName);
  37. }
  38. // Check if bean definition exists in this factory.
  39. BeanFactory parentBeanFactory = getParentBeanFactory();
  40. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  41. // Not found -> check parent.
  42. String nameToLookup = originalBeanName(name);
  43. if (args != null) {
  44. // Delegation to parent with explicit args.
  45. return (T) parentBeanFactory.getBean(nameToLookup, args);
  46. }
  47. else {
  48. // No args -> delegate to standard getBean method.
  49. return parentBeanFactory.getBean(nameToLookup, requiredType);
  50. }
  51. }
  52. if (!typeCheckOnly) {
  53. markBeanAsCreated(beanName);
  54. }
  55. try {
  56. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  57. checkMergedBeanDefinition(mbd, beanName, args);
  58. // Guarantee initialization of beans that the current bean depends on.
  59. String[] dependsOn = mbd.getDependsOn();
  60. if (dependsOn != null) {
  61. for (String dependsOnBean : dependsOn) {
  62. if (isDependent(beanName, dependsOnBean)) {
  63. throw new BeanCreationException("Circular depends-on relationship between '" +
  64. beanName + "' and '" + dependsOnBean + "'");
  65. }
  66. registerDependentBean(dependsOnBean, beanName);
  67. getBean(dependsOnBean);
  68. }
  69. }
  70. // Create bean instance.
  71. if (mbd.isSingleton()) {
  72. sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
  73. @Override
  74. public Object getObject() throws BeansException {
  75. try {
  76. return createBean(beanName, mbd, args);
  77. }
  78. catch (BeansException ex) {
  79. // Explicitly remove instance from singleton cache: It might have been put there
  80. // eagerly by the creation process, to allow for circular reference resolution.
  81. // Also remove any beans that received a temporary reference to the bean.
  82. destroySingleton(beanName);
  83. throw ex;
  84. }
  85. }
  86. });
  87. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  88. }
  89. else if (mbd.isPrototype()) {
  90. // It's a prototype -> create a new instance.
  91. Object prototypeInstance = null;
  92. try {
  93. beforePrototypeCreation(beanName);
  94. prototypeInstance = createBean(beanName, mbd, args);
  95. }
  96. finally {
  97. afterPrototypeCreation(beanName);
  98. }
  99. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  100. }
  101. else {
  102. String scopeName = mbd.getScope();
  103. final Scope scope = this.scopes.get(scopeName);
  104. if (scope == null) {
  105. throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
  106. }
  107. try {
  108. Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
  109. @Override
  110. public Object getObject() throws BeansException {
  111. beforePrototypeCreation(beanName);
  112. try {
  113. return createBean(beanName, mbd, args);
  114. }
  115. finally {
  116. afterPrototypeCreation(beanName);
  117. }
  118. }
  119. });
  120. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  121. }
  122. catch (IllegalStateException ex) {
  123. throw new BeanCreationException(beanName,
  124. "Scope '" + scopeName + "' is not active for the current thread; " +
  125. "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
  126. ex);
  127. }
  128. }
  129. }
  130. catch (BeansException ex) {
  131. cleanupAfterBeanCreationFailure(beanName);
  132. throw ex;
  133. }
  134. }
  135. // Check if required type matches the type of the actual bean instance.
  136. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
  137. try {
  138. return getTypeConverter().convertIfNecessary(bean, requiredType);
  139. }
  140. catch (TypeMismatchException ex) {
  141. if (logger.isDebugEnabled()) {
  142. logger.debug("Failed to convert bean '" + name + "' to required type [" +
  143. ClassUtils.getQualifiedName(requiredType) + "]", ex);
  144. }
  145. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  146. }
  147. }
  148. return (T) bean;
  149. }

如上所示,整体BeanFactory加载bean的过程是相当相当的复杂。这点也可以看出spring的代码写的非常优秀,一个方法做一件事情,减少了阅读代码的复杂程度。
getSingleton()
在Bean加载的第一行代码中,首先调用此方法。
   
   
  1. public Object getSingleton(String beanName) {
  2. return getSingleton(beanName, true);
  3. }
    
    
  1. /**
  2. * Return the (raw) singleton object registered under the given name.
  3. * <p>Checks already instantiated singletons and also allows for an early
  4. * reference to a currently created singleton (resolving a circular reference).
  5. * @param beanName the name of the bean to look for
  6. * @param allowEarlyReference whether early references should be created or not
  7. * @return the registered singleton object, or {@code null} if none found
  8. */
  9. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  10. Object singletonObject = this.singletonObjects.get(beanName);
  11. if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  12. synchronized (this.singletonObjects) {
  13. singletonObject = this.earlySingletonObjects.get(beanName);
  14. if (singletonObject == null && allowEarlyReference) {
  15. ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  16. if (singletonFactory != null) {
  17. singletonObject = singletonFactory.getObject();
  18. this.earlySingletonObjects.put(beanName, singletonObject);
  19. this.singletonFactories.remove(beanName);
  20. }
  21. }
  22. }
  23. }
  24. return (singletonObject != NULL_OBJECT ? singletonObject : null);
  25. }


getObjectForBeanInstance
对我们获取到的bean进行对应的类型检查。
   
   
  1. /**
  2. * Get the object for the given bean instance, either the bean
  3. * instance itself or its created object in case of a FactoryBean.
  4. * @param beanInstance the shared bean instance
  5. * @param name name that may include factory dereference prefix
  6. * @param beanName the canonical bean name
  7. * @param mbd the merged bean definition
  8. * @return the object to expose for the bean
  9. */
  10. protected Object getObjectForBeanInstance(
  11. Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
  12. // Don't let calling code try to dereference the factory if the bean isn't a factory.
  13. if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
  14. throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
  15. }
  16. // Now we have the bean instance, which may be a normal bean or a FactoryBean.
  17. // If it's a FactoryBean, we use it to create a bean instance, unless the
  18. // caller actually wants a reference to the factory.
  19. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
  20. return beanInstance;
  21. }
  22. Object object = null;
  23. if (mbd == null) {
  24. object = getCachedObjectForFactoryBean(beanName);
  25. }
  26. if (object == null) {
  27. // Return bean instance from factory.
  28. FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
  29. // Caches object obtained from FactoryBean if it is a singleton.
  30. if (mbd == null && containsBeanDefinition(beanName)) {
  31. mbd = getMergedLocalBeanDefinition(beanName);
  32. }
  33. boolean synthetic = (mbd != null && mbd.isSynthetic());
  34. object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  35. }
  36. return object;
  37. }
如上,我们可以看出主要是对FactoryBean的一些特殊处理。
createBean
如果缓存中不存在Bean,那么我们就需要createBean。
   
   
  1. // Create bean instance.
  2. if (mbd.isSingleton()) {
  3. sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
  4. @Override
  5. public Object getObject() throws BeansException {
  6. try {
  7. return createBean(beanName, mbd, args);
  8. }
  9. catch (BeansException ex) {
  10. // Explicitly remove instance from singleton cache: It might have been put there
  11. // eagerly by the creation process, to allow for circular reference resolution.
  12. // Also remove any beans that received a temporary reference to the bean.
  13. destroySingleton(beanName);
  14. throw ex;
  15. }
  16. }
  17. });
  18. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  19. }
具体的createBean
   
   
  1. protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
  2. throws BeanCreationException {
  3. if (logger.isDebugEnabled()) {
  4. logger.debug("Creating instance of bean '" + beanName + "'");
  5. }
  6. // Make sure bean class is actually resolved at this point.
  7. resolveBeanClass(mbd, beanName);
  8. // Prepare method overrides.
  9. try {
  10. mbd.prepareMethodOverrides();
  11. }
  12. catch (BeanDefinitionValidationException ex) {
  13. throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
  14. beanName, "Validation of method overrides failed", ex);
  15. }
  16. try {
  17. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  18. Object bean = resolveBeforeInstantiation(beanName, mbd);
  19. if (bean != null) {
  20. return bean;
  21. }
  22. }
  23. catch (Throwable ex) {
  24. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  25. "BeanPostProcessor before instantiation of bean failed", ex);
  26. }
  27. Object beanInstance = doCreateBean(beanName, mbd, args);
  28. if (logger.isDebugEnabled()) {
  29. logger.debug("Finished creating instance of bean '" + beanName + "'");
  30. }
  31. return beanInstance;
  32. }
继续
   
   
  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
  2. // Instantiate the bean.
  3. BeanWrapper instanceWrapper = null;
  4. if (mbd.isSingleton()) {
  5. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  6. }
  7. if (instanceWrapper == null) {
  8. instanceWrapper = createBeanInstance(beanName, mbd, args);
  9. }
  10. final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
  11. Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
  12. // Allow post-processors to modify the merged bean definition.
  13. synchronized (mbd.postProcessingLock) {
  14. if (!mbd.postProcessed) {
  15. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  16. mbd.postProcessed = true;
  17. }
  18. }
  19. // Eagerly cache singletons to be able to resolve circular references
  20. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  21. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  22. isSingletonCurrentlyInCreation(beanName));
  23. if (earlySingletonExposure) {
  24. if (logger.isDebugEnabled()) {
  25. logger.debug("Eagerly caching bean '" + beanName +
  26. "' to allow for resolving potential circular references");
  27. }
  28. addSingletonFactory(beanName, new ObjectFactory<Object>() {
  29. @Override
  30. public Object getObject() throws BeansException {
  31. return getEarlyBeanReference(beanName, mbd, bean);
  32. }
  33. });
  34. }
  35. // Initialize the bean instance.
  36. Object exposedObject = bean;
  37. try {
  38. populateBean(beanName, mbd, instanceWrapper);
  39. if (exposedObject != null) {
  40. exposedObject = initializeBean(beanName, exposedObject, mbd);
  41. }
  42. }
  43. catch (Throwable ex) {
  44. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  45. throw (BeanCreationException) ex;
  46. }
  47. else {
  48. throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  49. }
  50. }
  51. if (earlySingletonExposure) {
  52. Object earlySingletonReference = getSingleton(beanName, false);
  53. if (earlySingletonReference != null) {
  54. if (exposedObject == bean) {
  55. exposedObject = earlySingletonReference;
  56. }
  57. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  58. String[] dependentBeans = getDependentBeans(beanName);
  59. Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
  60. for (String dependentBean : dependentBeans) {
  61. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  62. actualDependentBeans.add(dependentBean);
  63. }
  64. }
  65. if (!actualDependentBeans.isEmpty()) {
  66. throw new BeanCurrentlyInCreationException(beanName,
  67. "Bean with name '" + beanName + "' has been injected into other beans [" +
  68. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  69. "] in its raw version as part of a circular reference, but has eventually been " +
  70. "wrapped. This means that said other beans do not use the final version of the " +
  71. "bean. This is often the result of over-eager type matching - consider using " +
  72. "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
  73. }
  74. }
  75. }
  76. }
  77. // Register bean as disposable.
  78. try {
  79. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  80. }
  81. catch (BeanDefinitionValidationException ex) {
  82. throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  83. }
  84. return exposedObject;
  85. }




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值