https://blog.csdn.net/qq_30257149/article/details/88016361?spm=1001.2014.3001.5502

  1. import org.springframework.beans.factory.BeanFactory;
  2. import org.springframework.beans.factory.xml.XmlBeanFactory;
  3. import org.springframework.core.io.ClassPathResource;
  4. public class XmlBeanFactoryTest {
  5. public static void main(String[] args) {
  6. // 资源加载
  7. ClassPathResource classPathResource = new ClassPathResource("spring-bean.xml");
  8. // XmlBeanFactory 加载资源并解析注册bean
  9. BeanFactory beanFactory = new XmlBeanFactory(classPathResource);
  10. // BeanFactory.getBean();
  11. UserBean userBean = (UserBean) beanFactory.getBean("userBean");
  12. System.out.println(userBean.getName());
  13. }
  14. }

BeanFactory.getBean()

  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. getBean(dependsOnBean);
  63. registerDependentBean(dependsOnBean, beanName);
  64. }
  65. }
  66. // Create bean instance.
  67. if (mbd.isSingleton()) {
  68. sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
  69. public Object getObject() throws BeansException {
  70. try {
  71. return createBean(beanName, mbd, args);
  72. }
  73. catch (BeansException ex) {
  74. // Explicitly remove instance from singleton cache: It might have been put there
  75. // eagerly by the creation process, to allow for circular reference resolution.
  76. // Also remove any beans that received a temporary reference to the bean.
  77. destroySingleton(beanName);
  78. throw ex;
  79. }
  80. }
  81. });
  82. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  83. }
  84. else if (mbd.isPrototype()) {
  85. // It's a prototype -> create a new instance.
  86. Object prototypeInstance = null;
  87. try {
  88. beforePrototypeCreation(beanName);
  89. prototypeInstance = createBean(beanName, mbd, args);
  90. }
  91. finally {
  92. afterPrototypeCreation(beanName);
  93. }
  94. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  95. }
  96. else {
  97. String scopeName = mbd.getScope();
  98. final Scope scope = this.scopes.get(scopeName);
  99. if (scope == null) {
  100. throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
  101. }
  102. try {
  103. Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
  104. public Object getObject() throws BeansException {
  105. beforePrototypeCreation(beanName);
  106. try {
  107. return createBean(beanName, mbd, args);
  108. }
  109. finally {
  110. afterPrototypeCreation(beanName);
  111. }
  112. }
  113. });
  114. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  115. }
  116. catch (IllegalStateException ex) {
  117. throw new BeanCreationException(beanName,
  118. "Scope '" + scopeName + "' is not active for the current thread; " +
  119. "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
  120. ex);
  121. }
  122. }
  123. }
  124. catch (BeansException ex) {
  125. cleanupAfterBeanCreationFailure(beanName);
  126. throw ex;
  127. }
  128. }
  129. // Check if required type matches the type of the actual bean instance.
  130. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
  131. try {
  132. return getTypeConverter().convertIfNecessary(bean, requiredType);
  133. }
  134. catch (TypeMismatchException ex) {
  135. if (logger.isDebugEnabled()) {
  136. logger.debug("Failed to convert bean '" + name + "' to required type [" +
  137. ClassUtils.getQualifiedName(requiredType) + "]", ex);
  138. }
  139. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  140. }
  141. }
  142. return (T) bean;
  143. }

doGetBean的源码比较长,那它都做了哪些事情呢: 1:转换对应的beanname,可能有很多人不理解,传入进来的不就应该是beanName嘛,其实传入的可能是BeanFactory,也可能是别名,如果是BeanFactory,就要去除它的修饰符,比如传入进来的&aa,就要转换成aa,但如果传入进来的是别名,就要取alias对应的最终的beanName,例如别名A指向了B的bean则返回B的beanName,如果别名A指向了别名B,别名B指向了C,则要返回C的BeanName; 2:检查单例中是否存在实例,会先从缓存中获取,下面会详细讲解; 3:判断原型实例是否存在循环依赖,比如A中有B,B中有A,这种情况只有单例模式才会尝试去创建,因为单例模式会提早包曝光实例,存在缓存中,原型模式是不允许的,会抛出类正在创建异常; 4:通过父BeanFactory获取bean; 5:将指定的bean标记为已经创建(或即将创建)。这允许bean工厂优化其缓存 6:获取RootBeanDefinition,在XmlBeanFactory解析的时候会将bean注册到beanDefinitionMap中,这里就是在beanDefinitionMap中get,如果不存在则会抛出bean not found异常,同时会将GenericBeanDefinition转换成RootBeanDefinition,因为存入时时GenericBeanDefinition; 7:检查BeanDefinition是否是abstract,如果是则抛出,bean is Aastract异常; 8:检查依赖,保证该bean所以依赖的bean都已经初始化,首先这里要了解depends-on用来表示一个bean A的实例化依靠另一个bean B的实例化, 但是A并不需要持有一个B的对象,如果需要的话就不用depends-on;不理解可以看这篇文章 9:判断bean的类型,是single还是proptotype,对应的创建bean,或者没有指定scope的判断,其中出现最多的方法就是getObjectForBeanInstance,后续会一点点的解析它的源码;

getSingleton(beanName);

  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. }

单例缓存获取:首先单例是只允许创建一次,并且单例支持解决循环依赖,第一步会从singletonObjects Map中获取单例,如果发现不存在的话,再通过singletonsCurrentlyInCreation判断下当前bean是否在创建,如果是则从提前曝光的Map earlySingletonObjects中获取,如果依旧不能存在则在singletonFactories中获取BeanFactory,通过getBean进行返回,反之结束了,缓存没有,只能去重新创建了;