spring源码分析之——spring bean的获取

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

前面分析了bean解析的过程,知道了bean都是以beandefinition的形式放在bean factory里面的。下面来看一下bean具体的获取过程。

Spring 提供了一个获取bean的工具方法:

WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc).getBean(String beanName);

OK,稍微追踪了一下代码,发现着落在了AbstraceBeanFactory下面:

Java代码

  1. public Object getBean(String name) throws BeansException {
  2. return doGetBean(name, null, null, false);
  3. }
  4. private T doGetBean(
  5. final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
  6. throws BeansException {
  7. final String beanName = transformedBeanName(name);
  8. Object bean;
  9. // Eagerly check singleton cache for manually registered singletons.
  10. Object sharedInstance = getSingleton(beanName);
  11. if (sharedInstance != null && args == null) {
  12. if (logger.isDebugEnabled()) {
  13. if (isSingletonCurrentlyInCreation(beanName)) {
  14. logger.debug(“Returning eagerly cached instance of singleton bean ‘” + beanName +
  15. “‘ that is not fully initialized yet – a consequence of a circular reference”);
  16. }
  17. else {
  18. logger.debug(“Returning cached instance of singleton bean ‘” + beanName + “‘”);
  19. }
  20. }
  21. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  22. }
  23. else {
  24. // Fail if we’re already creating this bean instance:
  25. // We’re assumably within a circular reference.
  26. if (isPrototypeCurrentlyInCreation(beanName)) {
  27. throw new BeanCurrentlyInCreationException(beanName);
  28. }
  29. // Check if bean definition exists in this factory.
  30. BeanFactory parentBeanFactory = getParentBeanFactory();
  31. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  32. // Not found -> check parent.
  33. String nameToLookup = originalBeanName(name);
  34. if (args != null) {
  35. // Delegation to parent with explicit args.
  36. return (T) parentBeanFactory.getBean(nameToLookup, args);
  37. }
  38. else {
  39. // No args -> delegate to standard getBean method.
  40. return parentBeanFactory.getBean(nameToLookup, requiredType);
  41. }
  42. }
  43. if (!typeCheckOnly) {
  44. markBeanAsCreated(beanName);
  45. }
  46. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  47. checkMergedBeanDefinition(mbd, beanName, args);
  48. // Guarantee initialization of beans that the current bean depends on.
  49. String[] dependsOn = mbd.getDependsOn();
  50. if (dependsOn != null) {
  51. for (String dependsOnBean : dependsOn) {
  52. getBean(dependsOnBean);
  53. registerDependentBean(dependsOnBean, beanName);
  54. }
  55. }
  56. // Create bean instance.
  57. if (mbd.isSingleton()) {
  58. sharedInstance = getSingleton(beanName, new ObjectFactory() {
  59. public Object getObject() throws BeansException {
  60. try {
  61. return createBean(beanName, mbd, args);
  62. }
  63. catch (BeansException ex) {
  64. // Explicitly remove instance from singleton cache: It might have been put there
  65. // eagerly by the creation process, to allow for circular reference resolution.
  66. // Also remove any beans that received a temporary reference to the bean.
  67. destroySingleton(beanName);
  68. throw ex;
  69. }
  70. }
  71. });
  72. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  73. }
  74. else if (mbd.isPrototype()) {
  75. // It’s a prototype -> create a new instance.
  76. Object prototypeInstance = null;
  77. try {
  78. beforePrototypeCreation(beanName);
  79. prototypeInstance = createBean(beanName, mbd, args);
  80. }
  81. finally {
  82. afterPrototypeCreation(beanName);
  83. }
  84. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  85. }
  86. else {
  87. String scopeName = mbd.getScope();
  88. final Scope scope = this.scopes.get(scopeName);
  89. if (scope == null) {
  90. throw new IllegalStateException(“No Scope registered for scope ‘” + scopeName + “‘”);
  91. }
  92. try {
  93. Object scopedInstance = scope.get(beanName, new ObjectFactory() {
  94. public Object getObject() throws BeansException {
  95. beforePrototypeCreation(beanName);
  96. try {
  97. return createBean(beanName, mbd, args);
  98. }
  99. finally {
  100. afterPrototypeCreation(beanName);
  101. }
  102. }
  103. });
  104. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  105. }
  106. catch (IllegalStateException ex) {
  107. throw new BeanCreationException(beanName,
  108. “Scope ‘” + scopeName + “‘ is not active for the current thread; “ +
  109. “consider defining a scoped proxy for this bean if you intend to refer to it from a singleton”,
  110. ex);
  111. }
  112. }
  113. }
  114. // Check if required type matches the type of the actual bean instance.
  115. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
  116. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  117. }
  118. return (T) bean;
  119. }

doGetBean….呃,好长的方法。慢慢研究一下。

Object sharedInstance = getSingleton(beanName);

这个方法首先去已经缓存了的Singleton里面寻找,如果没有,就到手工注入的singleton缓存里面寻找,如果没有,

再到缓存的FactoryBean类型的singleton里面寻找,如果还没有…继续doGetBean里面的下一步。

接下来如果当前beanfactory有parent,就到parentBeanFactory里面寻找,如果找不到,继续…

接下来就是获取spring里面当初解析出来的bean模板:RootBeanDefinition。然后

在当前factory下面注册一下依赖关系,下面就到了关键的步骤了,根据bean是singleton还是Prototype或者其他什么scope类型来分别定义bean的获取过程。下面以singleton为例来进行分析。

注意一下代码:

Java代码

  1. if (mbd.isSingleton()) {
  2. sharedInstance = getSingleton(beanName, new ObjectFactory() {
  3. public Object getObject() throws BeansException {
  4. try {
  5. return createBean(beanName, mbd, args);
  6. }
  7. catch (BeansException ex) {
  8. // Explicitly remove instance from singleton cache: It might have been put there
  9. // eagerly by the creation process, to allow for circular reference resolution.
  10. // Also remove any beans that received a temporary reference to the bean.
  11. destroySingleton(beanName);
  12. throw ex;
  13. }
  14. }
  15. });
  16. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  17. }

可见bean的生成委托给了createBean(name,mdb,args)方法。

这个方法的实现是在子类AbstractAutowireCapableBeanFactory里面。

Java代码

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

从上面的代码可以看出,先调用了resolveBeforeInstantiation方法。如果返回一个非空对象,那么就直接返回这个对象。 于是分析一下这个方法:

Java代码

  1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  2. Object bean = null;
  3. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  4. // Make sure bean class is actually resolved at this point.
  5. if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  6. bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
  7. if (bean != null) {
  8. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  9. }
  10. }
  11. mbd.beforeInstantiationResolved = (bean != null);
  12. }
  13. return bean;
  14. }

是不是似曾相识哪?那就对了 ! Aop的实现的核心啊,回想一下AbstractAutoProxyCreator,就是实现了InstantiationAwareBeanPostProcessor接口。从AbstractAutoProxyCreator的postProcessBeforeInstantiation代码可以很容易的看出,如果bean需要代理,那么返回一个代理类,否则返回Null.

结合当前代码,那就是如果产生了代理类,那么试着调用beanpostprocessors的postProcessAfterInitialization方法,然后返回这个代理类。从这里也可以看出,如果被代理的类定义了postProcessBeforeInitialization,init等方法,将根本没有调用的机会! 所以被代理类在实现BeanPostProcessor,InitilizingBean等接口时要非常小心。否则可能发现有些方法根本没有回调。

当然了,不一定非要产生代理类,也有可能有其他的实现了InstantiationAwareBeanPostProcessor接口的类也返回非空,这里就不详细分析。我大致看了一下,至少我看的几个实现了InstantiationAwareBeanPostProcessor接口的类是返回null的,除了AbstractAutoProxyCreator.

下面继续。如果调用InstantiationAwareBeanPostProcessor后依然返回Null,那么就继续下面的步骤,也就是激动人心的bean的instantiation过程了!这里是调用了doCreateBean(beanName, mbd, args)方法:

Java代码

  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() {
  29. public Object getObject() throws BeansException {
  30. return getEarlyBeanReference(beanName, mbd, bean);
  31. }
  32. });
  33. }
  34. // Initialize the bean instance.
  35. Object exposedObject = bean;
  36. try {
  37. populateBean(beanName, mbd, instanceWrapper);
  38. if (exposedObject != null) {
  39. exposedObject = initializeBean(beanName, exposedObject, mbd);
  40. }
  41. }
  42. catch (Throwable ex) {
  43. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  44. throw (BeanCreationException) ex;
  45. }
  46. else {
  47. throw new BeanCreationException(mbd.getResourceDescription(), beanName, “Initialization of bean failed”, ex);
  48. }
  49. }
  50. if (earlySingletonExposure) {
  51. Object earlySingletonReference = getSingleton(beanName, false);
  52. if (earlySingletonReference != null) {
  53. if (exposedObject == bean) {
  54. exposedObject = earlySingletonReference;
  55. }
  56. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  57. String[] dependentBeans = getDependentBeans(beanName);
  58. Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
  59. for (String dependentBean : dependentBeans) {
  60. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  61. actualDependentBeans.add(dependentBean);
  62. }
  63. }
  64. if (!actualDependentBeans.isEmpty()) {
  65. throw new BeanCurrentlyInCreationException(beanName,
  66. “Bean with name ‘” + beanName + “‘ has been injected into other beans [“ +
  67. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  68. “] in its raw version as part of a circular reference, but has eventually been “ +
  69. “wrapped. This means that said other beans do not use the final version of the “ +
  70. “bean. This is often the result of over-eager type matching – consider using “ +
  71. “‘getBeanNamesOfType’ with the ‘allowEagerInit’ flag turned off, for example.”);
  72. }
  73. }
  74. }
  75. }
  76. // Register bean as disposable.
  77. try {
  78. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  79. }
  80. catch (BeanDefinitionValidationException ex) {
  81. throw new BeanCreationException(mbd.getResourceDescription(), beanName, “Invalid destruction signature”, ex);
  82. }
  83. return exposedObject;
  84. }

汗~又是一个长方法。慢慢分析。

这个方法大致分为这么几步:

  1. 产生一个beanwrapper.

  2. 调用实现了MergedBeanDefinitionPostProcessors接口的类

  3. populateBean

  4. 初始化bean

  5. 注册产生的bean

下面分别就前几个步骤进行分析。

  1. 产生beanwrapper

Java代码

  1. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
  2. // Make sure bean class is actually resolved at this point.
  3. Class beanClass = resolveBeanClass(mbd, beanName);
  4. if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
  5. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  6. “Bean class isn’t public, and non-public access not allowed: “ + beanClass.getName());
  7. }
  8. if (mbd.getFactoryMethodName() != null) {
  9. return instantiateUsingFactoryMethod(beanName, mbd, args);
  10. }
  11. // Shortcut when re-creating the same bean…
  12. if (mbd.resolvedConstructorOrFactoryMethod != null && args == null) {
  13. if (mbd.constructorArgumentsResolved) {
  14. return autowireConstructor(beanName, mbd, null, null);
  15. }
  16. else {
  17. return instantiateBean(beanName, mbd);
  18. }
  19. }
  20. // Need to determine the constructor…
  21. Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  22. if (ctors != null ||
  23. mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
  24. mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
  25. return autowireConstructor(beanName, mbd, ctors, args);
  26. }
  27. // No special handling: simply use no-arg constructor.
  28. return instantiateBean(beanName, mbd);
  29. }

在这里可以看出,如果为bean定义了factoryMehtod或者constructor,那么将分别根据factoryMethod或construcgtor完成bean的初始化。否则调用如下方法:

Java代码

  1. protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
  2. try {
  3. Object beanInstance;
  4. final BeanFactory parent = this;
  5. if (System.getSecurityManager() != null) {
  6. beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
  7. public Object run() {
  8. return getInstantiationStrategy().instantiate(mbd, beanName, parent);
  9. }
  10. }, getAccessControlContext());
  11. }
  12. else {
  13. beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
  14. }
  15. BeanWrapper bw = new BeanWrapperImpl(beanInstance);
  16. initBeanWrapper(bw);
  17. return bw;
  18. }
  19. catch (Throwable ex) {
  20. throw new BeanCreationException(mbd.getResourceDescription(), beanName, “Instantiation of bean failed”, ex);
  21. }
  22. }
  23. 这里有一个InstantiationStrategy接口,这个接口定了bean初始化的策略。比如在

    当前类AbstractAutowireCapableBeanFactory下面一开始就定义了一个变量:

    Java代码

    1. private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

    可见,默认的初始化策略是CglibSubclassingInstantiationStrategy。

    这个策略的特殊之处就在于如果bean需要有method injection,那么就通过cglib代理的方式产生原本的bean class的一个子类从而实现method override.

    OK,至此BeanWrapper的生成基本清晰了。

    下面就是实现了MergedBeanDefinitionPostProcessors的类的调用了。这个接口的具体意思我还不是很清楚。稍后研究一下补全。

    然后就是populateBean. 这个方法就是把BeanDefinition里面维护的bean的属性populate到beanwrapper里面。

    接下来就是bean的初始化:

    if (exposedObject != null) {
    exposedObject = initializeBean(beanName, exposedObject, mbd);

    了解bean的初始化流程还是蛮有意义的:

    Java代码

    1. protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    2. if (System.getSecurityManager() != null) {
    3. AccessController.doPrivileged(new PrivilegedAction() {
    4. public Object run() {
    5. invokeAwareMethods(beanName, bean);
    6. return null;
    7. }
    8. }, getAccessControlContext());
    9. }
    10. else {
    11. invokeAwareMethods(beanName, bean);
    12. }
    13. Object wrappedBean = bean;
    14. if (mbd == null || !mbd.isSynthetic()) {
    15. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    16. }
    17. try {
    18. invokeInitMethods(beanName, wrappedBean, mbd);
    19. }
    20. catch (Throwable ex) {
    21. throw new BeanCreationException(
    22. (mbd != null ? mbd.getResourceDescription() : null),
    23. beanName, “Invocation of init method failed”, ex);
    24. }
    25. if (mbd == null || !mbd.isSynthetic()) {
    26. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    27. }
    28. return wrappedBean;
    29. }
    30. 可见初始化顺序是: XXAware接口的实现->postProcessBeforeInitialization->InitializingBean的afterPropertiesSet-> custom Init方法->postProcessAfterInitialization

      OK.这就是bean初始化的顺序啦!

      最后当然就是bean的注册了!

      Java代码

      1. protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
      2. AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
      3. if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
      4. if (mbd.isSingleton()) {
      5. // Register a DisposableBean implementation that performs all destruction
      6. // work for the given bean: DestructionAwareBeanPostProcessors,
      7. // DisposableBean interface, custom destroy method.
      8. registerDisposableBean(beanName,
      9. new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      10. }
      11. else {
      12. // A bean with a custom scope…
      13. Scope scope = this.scopes.get(mbd.getScope());
      14. if (scope == null) {
      15. throw new IllegalStateException(“No Scope registered for scope ‘” + mbd.getScope() + “‘”);
      16. }
      17. scope.registerDestructionCallback(beanName,
      18. new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      19. }
      20. }
      21. }

      这里面涉及到了bean以及与scope相关的生命周期的管理,需要单独分析一下。下篇文章再分析。


      来源:http://ddrv.cn

      赞(0) 打赏
      版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring源码分析之——spring bean的获取

      评论 抢沙发

      • 昵称 (必填)
      • 邮箱 (必填)
      • 网址

      © 2014 - 2019 Java 技术驿站   网站地图  | 

      icp 湘ICP备14000180

      >>> 网站已平稳运行:

      觉得文章有用就打赏一下文章作者

      支付宝扫一扫打赏

      微信扫一扫打赏