Spring IOC part source code analysis

One: Principle

  When the bean is a singleton, get the singleton bean from the cache; if not, create a singleton bean, use reflection to obtain the bean's constructor when creating a singleton bean, instantiate the bean through the constructor, and then assemble the bean and assemble the bean Dependency injection is performed at the same time; after that, the singleton bean is put into the cache without secondary creation.

  When the bean is multi-instance, the creation process is the same as the single-instance creation, but it will not be placed in the cache, then each call will create a new multi-instance bean

Two: source code analysis

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// Eagerly check singleton cache for manually registered singletons.
//bean是单例的话,从缓存读取
Object sharedInstance = getSingleton(beanName);
//如果缓存有,直接返回从缓存中获取的bean
if (sharedInstance != null && args == null) {
   if (logger.isDebugEnabled()) {
      if (isSingletonCurrentlyInCreation(beanName)) {
         logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
               "' that is not fully initialized yet - a consequence of a circular reference");
      }
      else {
         logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
      }
   }
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
........................
//缓存中没有,获取该bean的BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

2.1. Singleton

// Create bean instance.
//该BeanDefinition是单例的话
if (mbd.isSingleton()) {

   sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
      @Override
      public Object getObject() throws BeansException {
         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);
}

Note: The reason why a singleton is only created once

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

if (newSingleton) {
   addSingleton(beanName, singletonObject);
}

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton

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

synchronized (this.singletonObjects) {
   this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
   this.singletonFactories.remove(beanName);
   this.earlySingletonObjects.remove(beanName);
   this.registeredSingletons.add(beanName);
}

Create a singleton instance

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//实例化bean
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}

.......................
try {
//把依赖bean注入
   populateBean(beanName, mbd, instanceWrapper);
   if (exposedObject != null) {
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

Generate instances by reflection

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
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.
//instantiateBean实例化bean
return instantiateBean(beanName, mbd);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean

if (System.getSecurityManager() != null) {
   beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
      @Override
      public Object run() {
//实例化
         return getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }
   }, getAccessControlContext());
}
else {
//实例化
   beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition,java.lang.String,org.springframework.beans.factory.BeanFactory)

RootBeanDefinition bd

//用反射,获取class对象,拿到构造器constructorToUse
final Class<?> clazz = bd.getBeanClass();
constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);

org.springframework.beans.BeanUtils#instantiateClass(java.lang.reflect.Constructor<T>, java.lang.Object...)

//通过反射,用构造器生成实例
   ReflectionUtils.makeAccessible(ctor);
   return ctor.newInstance(args);

dependency injection

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

t-->

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
      mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

   // Add property values based on autowire by name if applicable.
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
//根据名字注入
      autowireByName(beanName, mbd, bw, newPvs);
   }

   // Add property values based on autowire by type if applicable.
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//根据类型注入
      autowireByType(beanName, mbd, bw, newPvs);
   }

   pvs = newPvs;
}

.....................
//将PropertyValues pvs放入 BeanWrapper bw中
applyPropertyValues(beanName, mbd, bw, pvs);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByName

String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
   if (containsBean(propertyName)) {
//递归调用,生成依赖链对象
      Object bean = getBean(propertyName);
//将bean的依赖bean放入容器中
      pvs.add(propertyName, bean);
      registerDependentBean(propertyName, beanName);
      if (logger.isDebugEnabled()) {
         logger.debug("Added autowiring by name from bean name '" + beanName +
               "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
      }
   }
   else {
      if (logger.isTraceEnabled()) {
         logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
               "' by name: no matching bean found");
      }
   }
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues

if (pvs instanceof MutablePropertyValues) {
   mpvs = (MutablePropertyValues) pvs;
   if (mpvs.isConverted()) {
      // Shortcut: use the pre-converted values as-is.
      try {
//将PropertyValues pvs放入 BeanWrapper bw中
         bw.setPropertyValues(mpvs);
         return;
      }
      catch (BeansException ex) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Error setting property values", ex);
      }
   }
   original = mpvs.getPropertyValueList();
}

2.2.  Multiple cases

//多例
else if (mbd.isPrototype()) {
   // It's a prototype -> create a new instance.
   Object prototypeInstance = null;
   try {
      beforePrototypeCreation(beanName);
//创建多例实例
      prototypeInstance = createBean(beanName, mbd, args);
   }
   finally {
      afterPrototypeCreation(beanName);
   }
   bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324909814&siteId=291194637