spring小結---bean實例化

上節講到aop,

繼續介紹bean的實例化過程,默認spring得bean是單例singleton

scope屬性可以理解成bean的生命週期
1、默認的值是singleton(単例),spring容器只會創建一個相應的bean實例,所有的對該bean的請求,spring容器都只返回這個實例。
2、還可取值proptotype(原型) ,每次請求都會獲得新的bean實例。
3、還可取值request、session、global session等(不常用)

finishBeanFactoryInitialization(beanFactory);

此方法:

................ 
  // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.實例化所有單例對象
   beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons()://根據beannames,調用getbean逐個實例化

這裏以下爲例

@Component("lmqsecond")
public class LmqDao23 {

    public void updatesecondquery()
    {
        System.out.println("updateqseonduery .............");
    }


}

進入

@Override
public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

由於lmqsecond不是懶加載,也不是factorybean,會直接進getbean()

然後進入

 doGetBean

如上所示:

Object sharedInstance = getSingleton(beanName);//對於普通類的bean由於初始化還沒實例,這裏肯定返回null, 但對於lazy加載的bean,由於終究是getbean()才實例化,有可能是之前被其他調用實例化,對於懶加載的再次調用就不返回null了,

getSingleton就是從如下map獲得:Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

   /** Logger available to subclasses */
   protected final Log logger = LogFactory.getLog(getClass());

   /** Cache of singleton objects: bean name --> bean instance */
   private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);


/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

..........................

繼續docreate流程:

.............................

if (!typeCheckOnly) {
   markBeanAsCreated(beanName); //把此beanname放到爲已創建集合
}

.....................

繼續實例化,如下,若有依賴,會率先實例化依賴,如下

記着無論是獲取bean實例還是初始新建bean實例,都是getbean()

繼續

// Create bean instance.
if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

看上面的 getSingleton()(一個是截圖劃紅線,另一個是加粗黑體),由於createbean有兩次getSingleton(),第一次只是檢查是有已經或者正在創建(因爲singletonCurrentlyInCreation不包含,還沒到創建的地步,直接返回null),

第二次getSingleton調用是爲了真正的創建(spring已經驗證了bean創建的前期工作,若爲空,則創建),下面的是第二次的getSingleton()

/**
 * Return the (raw) singleton object registered under the given name,
 * creating and registering a new one if none registered yet.
 * @param beanName the name of the bean
 * @param singletonFactory the ObjectFactory to lazily create the singleton
 * with, if necessary
 * @return the registered singleton object
 */
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         if (this.singletonsCurrentlyInDestruction) {
            throw new BeanCreationNotAllowedException(beanName,
                  "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                  "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
         }
         beforeSingletonCreation(beanName);//將beannname添加到singletonCurrentlyInCreation這樣一個set,表示beanname對應的bean正在創建中,
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {
            // Has the singleton object implicitly appeared in the meantime ->
            // if yes, proceed with it since the exception indicates that state.
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               throw ex;
            }
         }
         catch (BeanCreationException ex) {
            if (recordSuppressedExceptions) {
               for (Exception suppressedException : this.suppressedExceptions) {
                  ex.addRelatedCause(suppressedException);
               }
            }
            throw ex;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

看下 singletonObject = singletonFactory.getObject();

 

進去getObject(),由於是lamda表達式,回到表達式的createBean()

進入createBean();

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //這裏是在bean初始化之前應用後置處理器(不是aop的後置處理器啊,參考之前的aop源碼分析),由於此時還沒產生bean實例,

(實現InstantiationAwareBeanPostProcessor,可以返回裸對象(沒有屬性,沒有依賴的裸對象))
      if (bean != null) { //所以這些很不常用,因爲假設bean!=null,後面就返回了,沒有屬性自動裝配就返回bean實例,這種很少用,由於默認InstantiationAwareBeanPostProcessor實現是return null,所以繼續往下走,
         return bean;
      }
   }

   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

繼續走,docreatebean()//真正創建bean

進去

細看下

if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
   }

   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   if (mbd.getFactoryMethodName() != null)  { //spring的factorymethod配置一般是基於xml的bean配置,
     //類似<bean id='' class='' factory-method='returnNewLmq'>,其中class有個return new lmqserv();
   //同樣的包含@bean static方法也會被設置爲factorymethod,參考之前講的 appconfig,
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // Shortcut when re-creating the same bean... 構建bean的快捷方式,方便以後構建bean的原型對象(當被實例化多次,就標記爲true,用於原型對象構建)
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      if (autowireNecessary) {
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         return instantiateBean(beanName, mbd);
      }
   }

   // Need to determine the constructor...,由後置處理器決定返回哪些構造方法,因爲實例化需要有構造方法,
//默認構造函數,spring內部處理認爲沒有構造函數,帶參數除外,比如帶參

   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   //這裏提一下,rootBeanDefinition.AUTOWIRE_CONSTRUCTORspring的自動裝配模式不等於自動裝配技術默認爲no類型,而no是採用bytype來實現的,通過類型裝配不等於bytype(用於set方法)
   if (ctors != null ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {      
    //有參構造函數實例化對象,
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   // No special handling: simply use no-arg constructor.這裏是無參構造參數 
   return instantiateBean(beanName, mbd);

}

這裏先是無參構造,繼續看下instantiateBean(beanName, mbd);

* @return a BeanWrapper for the new instance
 */
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      final BeanFactory parent = this;
      if (System.getSecurityManager() != null) {
         beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
               getInstantiationStrategy().instantiate(mbd, beanName, parent),
               getAccessControlContext());
      }
      else {
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);//根據反射得到實例化對象
//如圖示,constructorTouse表示實例化要用到的構造函數 ,
    
 }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
   }
}

返回就得到了bean實例

然後new了beanwrapper

返回

接着返回

繼續返回

至此無參構造函數的bean實例完成

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章