Spring生命周期3 实例化前

Spring生命周期3 实例化前

​ 还是从刷新方法中的实例化非懒加载bean方法开始看,上一篇看了合并bean 其实也就是获取bean的第一行代码

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

@Override
public void preInstantiateSingletons() throws BeansException {
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
   for (String beanName : beanNames) {
      // 获取合并后的BeanDefinition
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            // 获取FactoryBean对象
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               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) {
                  // 创建真正的Bean对象(getObject()返回的对象)
                  getBean(beanName);
               }
            }
         }else {
            // 创建Bean对象
            getBean(beanName);
         }
      }
   }

获取到合并的bean定义后,判断bean是否是非静态的,懒加载的或者单例的,如果满足条件进行下一步。

然后判断是不是一个工厂beanisFactoryBean(beanName),我们只看最普通的创建流程,当做false看下面的getBean方法。

然后到入dogetbean方法,

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

然后开始分析这个方法,这个方法第一行转化了一下beanName

// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
// name有可能传入进来的是别名,那么beanName就是id
String beanName = transformedBeanName(name);

factoryBean的原本bean就是比普通的bean多个& 比如 一个factorybean a创建了一个bean b 那么getBean的时候传 a则取出b来,传&a取出 bean a来。

主动检查缓存池中有没有这个bean的实例。 (重要,循环依赖使用的这块代码,详细分析一下)

//主动检查单例缓存是否有手动注册的单例。
Object sharedInstance = getSingleton(beanName);
/**
 *返回在给定名称下注册的(原始)单例对象。<p>检查已经实例化的单例,并允许对当前创建的单例的早期引用(解析循环引用)。
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // 快速检查现有的实例,没有完全的单例锁
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
         synchronized (this.singletonObjects) {
            // Consistent creation of early reference within full singleton lock
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);
               if (singletonObject == null) {
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     singletonObject = singletonFactory.getObject();
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

其实大概意思就是 我先从一级缓存拿 一级缓存没有去二级缓存拿,二级缓存没有 但是三级缓存有则把三级缓存的取出来放到二级缓存,然后删除掉三级缓存的值。

然后在重新走doget’方法,从缓存中获取的实例肯定为null 所有走到esle方法,

// 如果我们已经创建了这个bean实例,则会失败:假设我们处于循环引用中。
if (isPrototypeCurrentlyInCreation(beanName)) {
   throw new BeanCurrentlyInCreationException(beanName);
}

这个方法是为了判断是否在创建中这个bean,暂时不深究,先把流程走通。

// 检查这个工厂中是否存在bean定义。
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
   // Not found -> check parent.
   // &&&&xxx---->&xxx
   String nameToLookup = originalBeanName(name);
   if (parentBeanFactory instanceof AbstractBeanFactory) {
      return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
            nameToLookup, requiredType, args, typeCheckOnly);
   } else if (args != null) {
      // Delegation to parent with explicit args.
      return (T) parentBeanFactory.getBean(nameToLookup, args);
   } else if (requiredType != null) {
      // No args -> delegate to standard getBean method.
      return parentBeanFactory.getBean(nameToLookup, requiredType);
   } else {
      return (T) parentBeanFactory.getBean(nameToLookup);
   }
}

这个方法是判断当前bean工厂没有这个bean的bean定义但是父工厂中有,去父工厂获取的方法,暂时跳过。

if (!typeCheckOnly) {
   markBeanAsCreated(beanName);
}

这个传进来的是false 标记一下这个bean在创建中。

StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
      .tag("beanName", name);

这句话也是一个标记,暂不深究。

然后获取合并bean,是否依赖其他bean创建,如果依赖先创建其他的bean

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

// 检查BeanDefinition是不是Abstract的
checkMergedBeanDefinition(mbd, beanName, args);

// 保证当前bean所依赖的bean的初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
   // dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
   for (String dep : dependsOn) {
      // beanName是不是被dep依赖了,如果是则出现了循环依赖
      if (isDependent(beanName, dep)) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
      }
      // dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
      registerDependentBean(dep, beanName);

      // 创建所依赖的bean
      try {
         getBean(dep);
      } catch (NoSuchBeanDefinitionException ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
      }
   }
}

如果bean是单例的创建bean的实例会走到

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;
      }
   });
   beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

createBean(beanName, mbd, args);就是创建bean的实例的方法了。

/**
 * 这个类的中心方法:创建一个bean实例,填充该bean实例,应用后处理程序,等等。
 *
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
   RootBeanDefinition mbdToUse = mbd;
   // 确保此时实际解析了bean类,如果动态解析的class不能存储在共享合并的bean定义中,则克隆bean定义。
   // 马上就要实例化Bean了,确保beanClass被加载了
   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);
      if (bean != 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.isTraceEnabled()) {
         logger.trace("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);
   }
}

到达这次的重点 实例化前的代码了

// 实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
/**
 * 应用实例化前后处理程序,解析指定bean是否有实例化前快捷方式。
 *
 * @param beanName the name of the bean
 * @param mbd      the bean definition for the bean
 * @return the shortcut-determined bean instance, or {@code null} if none
 */
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      // synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

applyBeanPostProcessorsBeforeInstantiation会调用缓存在内存中的所有实现了InstantiationAwareBeanPostProcessor

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
      if (result != null) {
         return result;
      }
   }
   return null;
}

的postProcessBeforeInstantiation方法。

实例化前的实现InstantiationAwareBeanPostProcessor接口中的postProcessBeforeInstantiation方法就可以在实例化前对bean进行一些操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值