sping-bean

The creation process of spring-bean

Method of creating bean
/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 */
@Override
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.
   // 确保 BeanDefinition 中的 Class 被加载
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    
    
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   // 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />
   // 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的地方看看对这两个标签的解析。
   // 我在附录中也对这两个标签的相关知识点进行了介绍,读者可以移步去看看
   try {
    
    
      // 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,
      // 在 《Spring AOP 源码分析》那篇文章中有解释,这里先跳过
      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);
      if (bean != null) {
    
    
         return bean;
      }
   }
   catch (Throwable ex) {
    
    
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
    
    
      // 重头戏,创建 bean
      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);
   }
}
Create Bean instance

doCreateBean.createBeanInstance

Not FactoryBean, instantiate Bean here;

  • instantiateUsingFactoryMethod is instantiated using a factory method, note that it is not a FactoryBean

  • Determine whether it is the first time to create, such as the second time to create a prototype bean. In this case, we can know from the first creation, whether to use a parameterless constructor or constructor dependency injection to complete the instantiation

  •    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);
          }
       }
     // 判断是否采用有参构造函数
       Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
       if (ctors != null ||
             mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
             mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
          
          
          // 构造函数依赖注入
          return autowireConstructor(beanName, mbd, ctors, args);
       }
    
       // 调用无参构造函数
       return instantiateBean(beanName, mbd);
    
  • Take a look at the parameterless constructor instantiateBean

  • 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);
          }
          // 包装一下,返回
          BeanWrapper bw = new BeanWrapperImpl(beanInstance);
          initBeanWrapper(bw);
          return bw;
       }
       catch (Throwable ex) {
          
          
          throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
       }
    }
    
  • Enter getInstantiationStrategy().instantiate(mbd, beanName, parent); instantiation

    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
          
          
       // Don't override the class with CGLIB if no overrides.
       // 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB,
       // 方法覆写 请参见附录"方法注入"中对 lookup-method 和 replaced-method 的介绍
       if (!bd.hasMethodOverrides()) {
          
          
          Constructor<?> constructorToUse;
          synchronized (bd.constructorArgumentLock) {
          
          
             constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
             if (constructorToUse == null) {
          
          
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
          
          
                   throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
          
          
                   if (System.getSecurityManager() != null) {
          
          
                      constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                   }
                   else {
          
          
                      constructorToUse = clazz.getDeclaredConstructor();
                   }
                   bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
          
          
                   throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
             }
          }
          // 利用构造方法进行实例化
          return BeanUtils.instantiateClass(constructorToUse);
       }
       else {
          
          
          // Must generate CGLIB subclass.
          // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,这里就不展开了。
          // tips: 因为如果不使用 CGLIB 的话,存在 override 的情况 JDK 并没有提供相应的实例化支持
          return instantiateWithMethodInjection(bd, beanName, owner);
       }
    }
    
Create Bean instance

​ After reading the createBeanInstance(…) method, let’s take a look at the populateBean(…) method, which is responsible for property setting and processing dependencies.

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param bw the BeanWrapper with bean instance
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    
    
   if (bw == null) {
    
    
      if (mbd.hasPropertyValues()) {
    
    
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
    
    
         // Skip property population phase for null instance.
         //空属性直接return
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.

   // 到这步的时候,bean 实例化完成(通过工厂方法或构造方法),但是还没开始属性设值,
   // InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改,
   // 我也没找到有实际的使用,所以我们暂且忽略这块吧
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    
    
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
         // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    
    
               return;
            }
         }
      }
   }
   // bean 实例的所有属性都在这里了
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      //@Resources按名字,是JDK的,@Autowired按类型,是Spring的。
      // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    
    
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // 通过类型装配。复杂一些
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    
    
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   if (hasInstAwareBpps || needsDepCheck) {
    
    
      if (pvs == null) {
    
    
         pvs = mbd.getPropertyValues();
      }
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
    
    
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               // 这里有个非常有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor
               // 对采用 @Autowired、@Value 注解的依赖进行设值,这里的内容也是非常丰富的,不过本文不会展开说了,感兴趣的读者请自行研究
               //CommonAnnotationBeanPostProcessor是处理@ReSource注解的
               //AutoWiredAnnotationBeanPostProcessor是处理@AutoWired注解的
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
    
    
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
    
    
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }

   if (pvs != null) {
    
    
      // 设置 bean 实例的属性值
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}
  • applyPropertyValues ​​method to set bean instance properties
initializeBean

Initialize the bean

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    
    
   if (System.getSecurityManager() != null) {
    
    
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    
    
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
    
    
      // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
    
    
      // BeanPostProcessor 的 postProcessBeforeInitialization 回调
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
    
    
      // 处理 bean 中定义的 init-method,
      // 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
    
    
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
    
    
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

Guess you like

Origin blog.csdn.net/qq_38893133/article/details/108452231