黑马程序员技术交流社区

标题: 【南京校区】spring-bean创建的生命周期与后置处理器的调用... [打印本页]

作者: 大蓝鲸小蟀锅    时间: 2020-2-26 09:23
标题: 【南京校区】spring-bean创建的生命周期与后置处理器的调用...
本帖最后由 大蓝鲸小蟀锅 于 2020-2-26 09:40 编辑

spring-bean创建的生命周期与后置处理器的调用点
1.第一次调用BeanPostProcess , InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()方法.
try {
   // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
   // 第一次调用BeanPostProcess   InstantiationAwareBeanPostProcessor这个处理器的postProcessBeforeInstantiation()方法.
   // 如果一个对象,不想通过spring进行维护, 只是想放入spring容器当中, 就实现此接口, 反回一个你需要的对象出来
   // 这边返回的对象不为null时, 这个beanName的的创建也聚完成了, spring的后置处理器不会对此对象进行操作.
   // spring不推荐使用, 是spring提供内部添加对象时调用的.
   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);
}


// Make sure bean class is actually resolved at this point.
// 判断是否有InstantiationAwareBeanPostProcessors的后置处理器.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   Class<?> targetType = determineTargetType(beanName, mbd);
   if (targetType != null) {
      // 如果调用postProcessBeforeInstantiation返回了一个对象, 那么就直接执行后置处理器,此对象的实例化就完成.
      bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
      if (bean != null) {
         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
      }
   }
}


一般来说 , 实现此接口返回的对象, 都是不需要经过spring帮我们创建对象了 , 不需要spring进行管理了.  spring不推荐我们使用, 而是交由spring内部自己调用的.
在spring-AOP有应用场景.
在我们开启AOP时.  添加 @EnableAspectJAutoProxy 注解.   基于spring的Import扩展  通过 ImportBeanDefinitionRegister, 帮我们注入了一个后置处理器.

AnnotationAwareAspectJAutoProxyCreator.   此类是 InstantiationAwareBeanPostProcessor的子类, 从写了 postProcessBeforeInstantiation()方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   Object cacheKey = getCacheKey(beanClass, beanName);


   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      // 再次判断beanClass中是否包含切面的注解 , 如果包含,保存到advisedBeans集合中,代表其实一个切面, 这样在bean实例化之后,
      // 执行beanPostProcess的postProcessAfterInitialization方法时, 不会对切面进行增强.
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }


   // Create proxy here if we have a custom TargetSource.
   // Suppresses unnecessary default instantiation of the target bean:
   // The TargetSource will handle target instances in a custom fashion.
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }


   return null;
}
  
  2. 第二次调用beanPostProcess, 来决定使用什么构造方法来创建对象. SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法.
// 第二次调用beanPostProcess , 用来决定是什么哪个构造方法创建对象.  SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors()方法.
// 由后置处理器来确定返回那些够着方法, 如果拿到就使用这个构造方法实例化. spring为什么要这样做呢?
// 我们可以通过反射直接拿到构造方法呀.
// beanPostProcess认为如果你没有没有构造方法,或者你构造方法是默认的空参构造, 那么此时返回的constructor= null.
// spring就认为你不存在特殊的构造方法, 所以直接跳过调用空参构造创建对象, 如果有特殊的构造方法,那么constructor != null,
// 就会使用你这个有参构造方法来创建对象.
// 但是如果有两个构造方法时 , 并且你没有指定primary的构造方法时, 也会返回null , 因为spring不知道你要使用哪个构造方法,所以还是让你走空参构造创建对象.
// 简单来说 , 如果有有且只有一个有参构造方法, 那么就返回这个有参构造方法, 如果有多个构造方法 , 就使用空参构造创建.
// 但是如果在解析beanDefinotion给他添加了构造方法, 那么就会使用到我们添加的构造方法.
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如何使用有参构造方法来创建对象呢?
// 有四个判断条件.
// 1. 通过上方,后置处理器,找到了唯一的有参构造
// 2. BeanDefinition设置为自动创建的模式  AUTOWIRE_CONSTRUCTOR
// 3. BeanDefinition我们设置了ConstructorArgumentValues, 还记得mybatis吗? 我们扫描完BeanDefinition后,给BeanDefinition设置使用什么构造参数和使用哪个beanClass.
// 4. 调用singletonObject是,传入的args就不为空, 是有值的, 明确告诉你, 我需要构造方法创建.
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   return autowireConstructor(beanName, mbd, ctors, args);
}


   3. 第三次调用beanPostProcess, 此方法用来缓存bean中的注解信息. 此时对象已经创建出来, 但是spring还没有创建成功, 因为各种属性还未添加.
            MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()方法.

synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
      try {
         //第三次调用 beanPostProcess , MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
         applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Post-processing of merged bean definition failed", ex);
      }
      mbd.postProcessed = true;
   }
}


  4. 第四次调用beanPostProcess, 用来提前暴露对象. spring认为此时, 对象仅仅是new了出来, 但是没有创建完成 , 对象走完spring的生命周期, 放入singletonObjects中, spring才算对象创建完成. 此时会把bean保存到singleonFactories中. 相当于一个中间集合, 如果对象在创建中, 因为引用其他对象时 , getSingleton()方法 会先到singletonFactories中获取, 如果获取不到 , 再通过 creatBean()创建对象 , 用来解决spring的循环引用问题 .
            SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference() 方法.
if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   // 会把正在创建的bean保存到singletonFactories中
   // 第四次调用beanPostProcess , SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法, 用来解决循环依赖的
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}


5. 第五次调用beanPostProcess, 用来判断你的bean需不需要完成属性填充 , 如果实现此接口 , 返回false , 那么spring不会帮我们填充属性.
            InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法.

// 第五次执行beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }
}


   6. 第六次调用beanPostProcess,
        AutowireAnnotationBeanPostProcessor 中的 postProcessProperrtyValues()方法.  主要使用来帮我们完成属性注入的 .
        CommonAnnotationBeanPostProcessor 中的  postProcessProperrtyValues()方法.  主要是用来处理@Resource的.

// 判断autowireMode是什么类型, 默认其实是 AUTOWIRE_BY_NO.
// 通过byName 或者 byType 拿到对应的属性, 其中spring会进行过滤 , 赋值给pvs ,让后置处理器去处理.
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.
   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;
}

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
   Set<String> result = new TreeSet<>();
   // 拿到我们手动设置的属性. 我们拿到beanDefinition后可以手动设置属性.
   PropertyValues pvs = mbd.getPropertyValues();
   // 拿到class 的所有属性.
   PropertyDescriptor[] pds = bw.getPropertyDescriptors();
   for (PropertyDescriptor pd : pds) {
      // 对所有的属性进行过滤.  那些属性是我们想要的.
      // 1. 需要set方法.
      // 2. spring过滤接口, 不存在.
      // 3. pvs中不包含的pd ,  我们手动添加给beanDefinition也需要过滤掉, 因为set方法肯定是class自己的,而不是我们手动添加的.
      // 4. 简单类型的也忽略掉.
      if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
            !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
         result.add(pd.getName());
      }
   }
   return StringUtils.toStringArray(result);
}


if (hasInstAwareBpps) {

   //在这一步处理使用后置处理器来处理对象, 例如require , autowire 注解
   // 第六次调用beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法.
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
         if (pvs == null) {
            return;
         }
      }
   }
}

@Override
public PropertyValues postProcessPropertyValues(
      PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {


   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
   try {
      // 通过inject注入属性.
      metadata.inject(bean, beanName, pvs);
   }
   catch (BeanCreationException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
   }
   return pvs;
}


    @Override
   protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
      Field field = (Field) this.member;
      Object value;
      if (this.cached) {
         value = resolvedCachedArgument(beanName, this.cachedFieldValue);
      }
      else {
         DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
         desc.setContainingClass(bean.getClass());
         Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
         Assert.state(beanFactory != null, "No BeanFactory available");
         TypeConverter typeConverter = beanFactory.getTypeConverter();
         try {
            // 关键代码 , 从spring的beanFactory中获取对象
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
         }
         catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
         }
         synchronized (this) {
            if (!this.cached) {
               if (value != null || this.required) {
                  this.cachedFieldValue = desc;
                  registerDependentBeans(beanName, autowiredBeanNames);
                  if (autowiredBeanNames.size() == 1) {
                     String autowiredBeanName = autowiredBeanNames.iterator().next();
                     if (beanFactory.containsBean(autowiredBeanName) &&
                           beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                        this.cachedFieldValue = new ShortcutDependencyDescriptor(
                              desc, autowiredBeanName, field.getType());
                     }
                  }
               }
               else {
                  this.cachedFieldValue = null;
               }
               this.cached = true;
            }
         }
      }
      if (value != null) {
         ReflectionUtils.makeAccessible(field);
         field.set(bean, value);
      }
   }
}

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
      throws BeansException {

    // 调用到geiBean() , 然后通过getSingleton()获取.
   return beanFactory.getBean(beanName);
}


   7.  第七次调用beanPostProcess,   此时对象已经创建成功, 并且属性填充完毕. 基本上一个bean对象已经创建完成.

if (mbd == null || !mbd.isSynthetic()) {
   // BeanPostProcess有两个方法 ,这里先执行  postProcessBeforeInitialization 方法.
   // 第七次执行BeanPostProcess , 真正执行的BeanPostProcess的postProcessBeforeInitialization()方法.
   // 之前执行的都是实现类中自己定义的扩展功能的方法.
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}


@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    //如果你的bean是ImportAware

   if (bean instanceof ImportAware) {
      ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
      AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
      if (importingClass != null) {
         ((ImportAware) bean).setImportMetadata(importingClass);
      }
   }
   return bean;
}


  8. 第八次调用beanPostProcess, 创建对象的最后一步, aop的代理就是在此处创建.
if (mbd == null || !mbd.isSynthetic()) {
   // 处理BeanPostProcess的另一个方法 . postProcessAfterInitialization , aop就在此时做的.
   // 第八次执行beanPostProcess, 真正执行的beanPostProcess的postProcessAfterInitialization()方法.
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}


protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {
   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
   // spring写的代理工厂 , 工厂模式的使用
   ProxyFactory proxyFactory = new ProxyFactory();
   // 这只proxyFactory工厂的属性, 从这个类中, 因为此类继承 ProxyConfig
   proxyFactory.copyFrom(this);

   // 判断使用那种方式进行代理 , cglib 还是 jdk
   // 因为在new ProxyFactory工厂时, 父类会创建 AopProxyFactory工厂,
   // 此类的createAopProxy(),中调用proxyTargetClass属性, 如果是true,就使用cglib , spring默认是false.
   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   // 拿到我们切面中的所有方法.
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);
   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   return proxyFactory.getProxy(getProxyClassLoader());
}


以上就是spring扫描的我们对应的类之后 , 通过beanDefinition创建对象的流程. 欢迎讨论












欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2