Spring源码解读:一个单例Bean的生命周期

本文详细解读了Spring框架中DefaultListableBeanFactory如何创建和管理单例Bean的生命周期,包括从实例化、属性填充到初始化、销毁的全过程。文章分析了不同阶段涉及的接口,如InstantiationAwareBeanPostProcessor、BeanDefinition、BeanPostProcessor等,以及如何通过这些接口进行拓展和定制化操作。
摘要由CSDN通过智能技术生成

在以前梳理SpringBean创建的源码的时候有说过,画一张其涉及的接口的流程图,现在补上这个坑。同时以前主要是重点关注Spring的代码逻辑(导致我自己现在去看也不是很能看下去)。在这个重读系列,我们从其的整体结构出发,如果不是特别的重要的逻辑,我们就不关注里面的一些细节逻辑。

一、DefaultListableBeanFactory

1、结构

SpringMVC的Bean容器的实现核心类就是这个DefaultListableBeanFactory,然后我们来看下其的层次结构

Spring源码解读:一个单例Bean的生命周期

 

​ 其继承的类我们需要注意DefaultSingletonBeanRegistry、AbstractBeanFactory,其中DefaultSingletonBeanRegistry类是单例Bean的存放,AbstractBeanFactory是获取Bean的整个逻辑处理。

​ 下面我们就直接来看获取Bean的过程,以下画的时序图并不是标准的时序图,只是为了说明概况整个流程,所以如果要画标准的时序图的话请学习资料。

二、第一阶段(拓展直接创建对象实例)

​ 在这里可以由InstantiationAwareBeanPostProcessor接口直接产生Bean,但Spring的注释是说,这个接口一般是供Spring框架内部使用的,不推荐直接使用这个接口。如果一定要拓展,其推荐使用InstantiationAwareBeanPostProcessorAdapter接口

public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {
  

​ 可以看到其实现了SmartInstantiationAwareBeanPostProcessor接口。

1、能拓展的接口

​ 这一阶段能拓展的接口``InstantiationAwareBeanPostProcessor,官方建议通过InstantiationAwareBeanPostProcessorAdapter`

2、流程图

Spring源码解读:一个单例Bean的生命周期

 

​ 这就是获取Bean的第一阶段,可以看到其是通过InstantiationAwareBeanPostProcessor来产生Bean的,并且可以看到其调用的其他拓展接口就只有BeanPostProcessor接口了。

3、整体流程介绍

​ 1)、其的获取Bean的发起方法一般是getBean(String name),当然也可以Class作为入参getBean(Class<T> requiredType),不过其最终也还是会被转换为name的形式获取

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
   return getBean(requiredType, (Object[]) null);
}

​ 2)、我们可以看到其调用的是doGetBean方法

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly)

​ 3)、然后可以看到如果是单例的话,其是调用getSingleton方法获取对应的Bean实例,但其又是通过createBean方法其创建的

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);
}

​ 4)、然后通过mbdToUse.prepareMethodOverrides()再调用hasMethodOverrides()方法判断处理<lookup-method>标签。

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

   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
      ..........
   // 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) {
      ........
   }

   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      return beanInstance;
   }
  .........
}
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
   // Check that lookup methods exists.
   if (hasMethodOverrides()) {
      Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
      synchronized (overrides) {
         for (MethodOverride mo : overrides) {
            prepareMethodOverride(mo);
         }
      }
   }
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		.........
		else if (count == 1) {
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			mo.setOverloaded(false);
		}
	}

​ 5)、然后通过resolveBeforeInstantiation看能不能获取到Bean。

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

​ 6)、通过hasInstantiationAwareBeanPostProcessors()方法看有没有InstantiationAwareBeanPostProcessors接口的实现类,如果有,就调用该接口的postProcessBeforeInstantiation方法,如果这个接口有创建返回Bean,再调用BeanPostProcessor接口的postProcessAfterInitialization的方法,这样就完成了Bean的创建。

@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.
      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;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值