Spring Bean生成过程

文章详细阐述了Spring在启动时如何扫描BeanDefinition,从ResourcePatternResolver获取.class文件,到BeanDefinition的生成与合并。接着介绍了Bean的加载过程,包括类加载和生命周期中的各个阶段,如InstantiationAwareBeanPostProcessor的作用。最后提到了初始化前后的扩展点,如@PostConstruct注解的执行和AOP的实现时机。

Spring启动的时候会进行扫描,会先调用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.scanCandidateComponents(String basePackage) 扫描某个包路径,并得到BeanDefinition的Set集合。

一、生成BeanDeafinition

spring扫描流程:

  1. 通过 ResourcePatternResolver(资源模型解析器)获取指定包路径下所有的.class文件,并且包装返回 Resource 数组
  2. 遍历Resource数组,通过 MetadataReaderFactory(元数据读取器工厂)解析 Resource对象,获取 MetadataReader(class文件信息)(在Spring源码中 MetadataReaderFactory 具体的实现类为CachingMetadataReaderFactory,MetadataReader 的具体实现类为SimpleMetadataReader)
  3. 判断 MetadataReader 是否满足 excludeFilters、includeFilters条件,满足则把 MetadataReader 包装为一个 ScannedGenericBeanDefinition 对象,并且设置 resource属性
  4. 判断 ScannedGenericBeanDefinition 不为内部类并且不是抽象类和接口,或者是抽象的并且方法中包含Lookup注解。满足则添加到Set 中。

二、合并BeanDefinititon

<bean id="parent" class="com.zhouyu.service.Parent" scope="prototype"/>

<bean id="child" class="com.zhouyu.service.Child" parent="parent"/>

child 默认为单例,但是它的paretn为prototype,所以会属性继承,也会变为多例。在Set中保存的是 BeanDefinition 的子类 RootBeanDefinition ,当类加的时候,也是加载 RootBeanDefinition

三、类加载

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);

获取当前当前 BeanDefinition 对应的class,获取类加载器,然后加载。类加载器优先返回当前线程的ClassLoader,如果为null,则返回 ClassUtils 的类加载器。如果 CalssUtils 的类加载器为null,则认为 Bootstrap 类加载器加载的 ClassUtils,返回 Bootstrap 类加载器

四、Bean的生命周期

  1. 实例化前
    在Spring中提供很多扩展点,允许用户在某些或某个Bean实例化前做一些操作,这个扩展点就叫 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantition()。
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    System.out.println("实例化前");
    if ("filterConfig".equals(beanName)) {
        return beanClass;
    }
    return null;
}

该方法默认返回值为null,如果我们返回了一个具体的对象,就表示不需要spring去实例化,并且这个对象如果有@Value @Autowried等注解,都不会生效,也就是spring的依赖注入不会去执行了,直接进入初始化后。

  1. 实例化
    a. 通过BeanDefinition去创建对象。如果BeanDefinition中设置了 Supplier,则返回Supplier.get()方法的对象。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    ...
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
       return obtainFromSupplier(instanceSupplier, beanName);
    }
    ...
}

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
   Object instance;

   String outerBean = this.currentlyCreatedBean.get();
   this.currentlyCreatedBean.set(beanName);
   try {
      instance = instanceSupplier.get();
   }
   finally {
      if (outerBean != null) {
         this.currentlyCreatedBean.set(outerBean);
      }
      else {
         this.currentlyCreatedBean.remove();
      }
   }
   if (instance == null) {
      instance = new NullBean();
   }
   BeanWrapper bw = new BeanWrapperImpl(instance);
   initBeanWrapper(bw);
   return bw;
}

b. 如果没有设置 Supplier,则检查 BeanDefinition 是否设置了 factoryMethodName,如果有,则通过工厂方法去创建对象。@Bean的方式就是用 factoryMethodName 创建 Bean,@Bean就是factory‐method,@Configuration就是 factory‐bean。如果@Bean所所注解的方法是static的,那么对应的就是方式一。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    ...
    if (mbd.getFactoryMethodName() != null) {
       return instantiateUsingFactoryMethod(beanName, mbd, args);
    }
    ...
}

方式一

<bean id="userService" class="com.zhouyu.service.UserService" factory‐method="createUserService" />

方式二

<bean id="commonService" class="com.zhouyu.service.CommonService"/>

<bean id="userService1" factory‐bean="commonService" factory‐method="createUserService"/>
  1. BeanDefinition后置处理器
    在Bean实例化后,接下来应该是属性赋值。但是在真正给属性赋值之前,Spring又提供了一个扩展点,MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法,可以对此时的BeanDefinition进行加工。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}
  1. 实例化后
    在处理完BeanDefinition后,Spring在InstantiationAwareBeanPostProcessor中又提供了一个扩展点,postProcessAfterInstantiation()方法,该方法可以对实例化对象、beanName进行加工。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   return true;
}
  1. 自动注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
   // Add property values based on autowire by name if applicable.
   if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
   }
   // Add property values based on autowire by type if applicable.
   if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
   }
   pvs = newPvs;
}
  1. 属性处理
    通过InstantiationAwareBeanPostProcesor.psotProcessProPerties()方法实现,比如对 @Autowired @Resource @Value 注解的处理
for (BeanPostProcessor bp : getBeanPostProcessors()) {
   if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
         if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
         }
         pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            return;
         }
      }
      pvs = pvsToUse;
   }
}
  1. 执行Aware
    属性赋值完成以后,Spring会执行Awar回调。
    BeanNameAware:设置bean名称回调
    BeanClassLoaderAware:设置bean的类加载器回调
    BeanFactoryAware:设置bean的beanFactory回调
private void invokeAwareMethods(final String beanName, final Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}
  1. 初始化前
    BeanPostProcessor.postProcessBeforeInitialization()方法也是Spring的一个扩展点,在初始化前执行,@PostConstruct注解就是在初始化前执行
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
  1. 初始化
    a.如果当前bean对象实现了InitializingBean接口,就调用afterPropertiesSet()方法。
    b.如果当前BeanDefinition 中设置了initMethodName,则执行指定的初始化方法。
  2. 初始化后
    获取所有的BeanPostProcessor,执行 postProcessAfterInitialization()方法。在这个步骤中,对Bean进行最终的处理,Spring的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的对象。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值