1 Star 0 Fork 156

南风不竞 / Spring-Analysis

forked from huifer / Code-Analysis 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Spring-SimpleInstantiationStrategy.md 7.90 KB
一键复制 编辑 原始数据 按行查看 历史
huifer 提交于 2020-12-03 11:20 . feat: 0.0.9

Spring SimpleInstantiationStrategy

  • 类全路径: org.springframework.beans.factory.support.SimpleInstantiationStrategy

成员变量

SimpleInstantiationStrategy 中仅有一个变量 用来存储 工厂方法(FactoryMethod)

    private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();

方法分析

从 beanFactory 中返回 对应的 BeanName 实例对象

  • 方法签名: org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)

第一部分代码分析

  • 先来看一看第一部分的代码
第一部分代码
     if (!bd.hasMethodOverrides()) {
         // 构造方法
Constructor<?> constructorToUse;
// 锁
         synchronized (bd.constructorArgumentLock) {
           // 提取构造函数
             constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
   if (constructorToUse == null) {
      // 获取 bean Class
      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);
     }
  • 第一部分代码的核心操作都是在找 Constructor 构造函数类. 寻找方式有
    1. 从**BeanDefinition**中的resolvedConstructorOrFactoryMethod 属性获取
    2. BeanDefinition 中获取 BeanClass 后在通过 Class获取

在获取到Constructor后交给BeanUtils.instantiateClass 进行Bean构造

  • 有关BeanUtils.instantiateClass的分析可以查看这篇文章

接下来看第二段代码

else {
    // Must generate CGLIB subclass.
    // cglib 构造 . 本质还是 构造函数创建
    return instantiateWithMethodInjection(bd, beanName, owner);
}

第二段代码就涉及到 CGLIB 的对象构造了 , 即InstantiationStrategy的另一个实现类CglibSubclassingInstantiationStrategy

关于 CglibSubclassingInstantiationStrategy 的分析查看这篇文章

详细代码如下
  @Override
  public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
      // Don't override the class with CGLIB if no overrides.
// 不是 cglib
      // 重写方法列表是否存在
      if (!bd.hasMethodOverrides()) {
          // 构造方法
   Constructor<?> constructorToUse;
   // 锁
          synchronized (bd.constructorArgumentLock) {
           // 提取构造函数
              constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
      if (constructorToUse == null) {
         // 获取 bean Class
         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 构造 . 本质还是 构造函数创建
          return instantiateWithMethodInjection(bd, beanName, owner);
      }
  }

从 beanFactory 中返回 对应的 BeanName 实例对象, 指定构造函数

在上面的分析中我们已经认识到了两种初始化方式.

  1. 通过类自身创建
  2. 通过 CGLIB 创建

在这个方法中也是这样两种

  • 方法签名: org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.reflect.Constructor<?>, java.lang.Object...)
第一部分代码
if (!bd.hasMethodOverrides()) {
          if (System.getSecurityManager() != null) {
              // use own privileged to change accessibility (when security is on)
              AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                  ReflectionUtils.makeAccessible(ctor);
                  return null;
              });
          }
          return BeanUtils.instantiateClass(ctor, args);
      }

第一部分有一次指向了方法BeanUtils.instantiateClass

有关BeanUtils.instantiateClass的分析可以查看这篇文章

第二部分代码

// cglib 的初始化
      else {
          return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
      }

从 beanFactory 中返回 对应的 BeanName 实例对象, 通过指定的FactoryMethod

  • 方法签名: org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.Object, java.lang.reflect.Method, java.lang.Object...)

执行事项

  1. 执行参数的Method 将结果返回
  2. 设置currentlyInvokedFactoryMethod
详细代码如下
        if (System.getSecurityManager() != null) {
// 设置 accessible
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                ReflectionUtils.makeAccessible(factoryMethod);
                return null;
            });
        }
        else {
           // 设置 accessible
            ReflectionUtils.makeAccessible(factoryMethod);
        }

        // 获取 工厂函数
        Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
        try {
           // 找到 factory method 调用执行
            currentlyInvokedFactoryMethod.set(factoryMethod);
            // 反射执行工厂函数
            Object result = factoryMethod.invoke(factoryBean, args);
            if (result == null) {
                result = new NullBean();
            }
            return result;
        }
        finally {
            if (priorInvokedFactoryMethod != null) {
                currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
            }
            else {
                currentlyInvokedFactoryMethod.remove();
            }
        }
Java
1
https://gitee.com/limengcanyu/spring-analysis.git
git@gitee.com:limengcanyu/spring-analysis.git
limengcanyu
spring-analysis
Spring-Analysis
master

搜索帮助