实例化(Spring bean)

123 阅读5分钟

实例化

AbstractAutowireCapableBeanFactory
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
   ...
   // 获取实例化策略并且进行实例化操作
   beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
   ...
}

概览

strategy.png

InstantiationStrategy

InstantiationStrategy.png

/**
 * 实例化策略接口,子类被用来根据rootBeanDefinition来创建实例对象
 * 这是一个策略,因为各种方法是可能的,包括使用CGLIB动态支持创建子类方法注入
 */
public interface InstantiationStrategy {

   /**
    * 使用默认构造方法进行实例化
    */
   Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
         throws BeansException;

   /**
    * 通过指定构造器来进行实例化 Constructor
    */
   Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
         Constructor<?> ctor, Object... args) throws BeansException;

   /**
    * 通过指定工厂方法来进行实例化  factoryMethod
    */
   Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
         @Nullable Object factoryBean, Method factoryMethod, Object... args)
         throws BeansException;
}
/**
 * 简单的对象实例化策略
 */
public class SimpleInstantiationStrategy implements InstantiationStrategy {

   // FactoryMethod的ThreadLocal对象
   private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();

   /**
    * 返回当前现成所有的FactoryMethod变量值
    */
   @Nullable
   public static Method getCurrentlyInvokedFactoryMethod() {
      return currentlyInvokedFactoryMethod.get();
   }


   /**
    * 如果发现是有方法重载的,就需要用cglib来动态代理,如果没有就直接获取默认构造方法实例化
    */
   @Override
   public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
      // Don't override the class with CGLIB if no overrides.
      // bd对象定义中,是否包含MethodOverride列表,spring中有两个标签参数会产生MethodOverrides,分别是lookup-method,replaced-method
      // 没有MethodOverrides对象,可以直接实例化
      if (!bd.hasMethodOverrides()) {
         // 实例化对象的构造方法
         Constructor<?> constructorToUse;
         // 锁定对象,使获得实例化构造方法线程安全
         synchronized (bd.constructorArgumentLock) {
            // 查看bd对象里使用否含有构造方法
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            // 如果没有
            if (constructorToUse == null) {
               // 从bd中获取beanClass
               final Class<?> clazz = bd.getBeanClass();
               // 如果要实例化的beanDefinition是一个接口,则直接抛出异常
               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中的属性
                  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);
      }
   }

   /**
    * 此方法没有做任何的实现,直接抛出异常,可以由子类重写覆盖
    */
   protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
      throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
   }

   /**
    * 使用有参构造方法进行实例化
    */
   @Override
   public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
         final Constructor<?> ctor, Object... args) {

      // 检查bd对象是否有MethodOverrides对象,没有的话则直接实例化对象
      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);
      }
      else {
         // 如果有methodOverride对象,则调用方法来进行实现
         return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
      }
   }

   /**
    * 此方法没有做任何的实现,直接抛出异常,可以由子类重写覆盖
    */
   protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName,
         BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {

      throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
   }

   /**
    * 使用工厂方法进行实例化
    */
   @Override
   public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
         @Nullable Object factoryBean, final Method factoryMethod, Object... args) {

      try {
         // 是否包含系统安全管理器
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               ReflectionUtils.makeAccessible(factoryMethod);
               return null;
            });
         }
         else {
            // 通过反射工具类设置访问权限
            ReflectionUtils.makeAccessible(factoryMethod);
         }

         // 获取原有的Method对象
         Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
         try {
            // 设置当前的Method
            currentlyInvokedFactoryMethod.set(factoryMethod);
            // 使用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();
            }
         }
      }
      catch (IllegalArgumentException ex) {
         throw new BeanInstantiationException(factoryMethod,
               "Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
               "args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
      }
      catch (IllegalAccessException ex) {
         throw new BeanInstantiationException(factoryMethod,
               "Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
      }
      catch (InvocationTargetException ex) {
         String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
         if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
               ((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
            msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
                  "declaring the factory method as static for independence from its containing instance. " + msg;
         }
         throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
      }
   }

}
/**
 * beanFactory中的对象默认实例化策略
 */
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {

   /**
    * 如果没有override方法覆盖的话,那么索引位置为0
    */
   private static final int PASSTHROUGH = 0;

   /**
    * 如果有lookup-method的覆盖,那么索引位置为1
    */
   private static final int LOOKUP_OVERRIDE = 1;

   /**
    * 如果有replace-method的覆盖,那么索引位置为2
    */
   private static final int METHOD_REPLACER = 2;


   // 子类重写SimpleInstantiationStrategy中的instantiateWithMethodInjection方法
   @Override
   protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
      return instantiateWithMethodInjection(bd, beanName, owner, null);
   }

   @Override
   protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
         @Nullable Constructor<?> ctor, Object... args) {

      // Must generate CGLIB subclass...
      // 必须生成一个cglib的子类
      return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
   }


   /**
    * An inner class created for historical reasons to avoid external CGLIB dependency
    * in Spring versions earlier than 3.2.
    */
   private static class CglibSubclassCreator {

      // 此处定义了一个回调类型的数组,后面MethodOverrideCallbackFilter通过指定下标获取对应的拦截
      private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]
            {NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};

      private final RootBeanDefinition beanDefinition;

      private final BeanFactory owner;

      // 构造方法
      CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
         this.beanDefinition = beanDefinition;
         this.owner = owner;
      }

      /**
       * 实例化入口:动态构造子类
       */
      public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
         // 根据beanDefinition来创建一个cglib的子类
         Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
         Object instance;
         // 如果构造器等于空,那么直接通过反射来实例化对象
         if (ctor == null) {
            instance = BeanUtils.instantiateClass(subclass);
         }
         else {
            try {
               // 通过cglib对象来根据参数类型获取对应的构造器
               Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
               // 通过构造器来获取对象
               instance = enhancedSubclassConstructor.newInstance(args);
            }
            catch (Exception ex) {
               throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
                     "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
            }
         }
         // SPR-10785: set callbacks directly on the instance instead of in the
         // enhanced class (via the Enhancer) in order to avoid memory leaks.
         // https://jira.spring.io/browse/SPR-10785
         Factory factory = (Factory) instance;
         factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
               new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
               new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
         return instance;
      }

      /**
       * Create an enhanced subclass of the bean class for the provided bean
       * definition, using CGLIB.
       */
      private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
         // cglib规定用法,对原始class进行增强,并设置callback
         Enhancer enhancer = new Enhancer();
         enhancer.setSuperclass(beanDefinition.getBeanClass());
         enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
         if (this.owner instanceof ConfigurableBeanFactory) {
            ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
            enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
         }
         // 过滤,自定义逻辑来指定调用的callback下标
         enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
         // 只是产生class就直接指定callback类型,跟上面指定的callbackFilter对应
         enhancer.setCallbackTypes(CALLBACK_TYPES);
         return enhancer.createClass();
      }
   }


   /**
    * Class providing hashCode and equals methods required by CGLIB to
    * ensure that CGLIB doesn't generate a distinct class per bean.
    * Identity is based on class and bean definition.
    */
   private static class CglibIdentitySupport {

      private final RootBeanDefinition beanDefinition;

      public CglibIdentitySupport(RootBeanDefinition beanDefinition) {
         this.beanDefinition = beanDefinition;
      }

      public RootBeanDefinition getBeanDefinition() {
         return this.beanDefinition;
      }

      @Override
      public boolean equals(@Nullable Object other) {
         return (other != null && getClass() == other.getClass() &&
               this.beanDefinition.equals(((CglibIdentitySupport) other).beanDefinition));
      }

      @Override
      public int hashCode() {
         return this.beanDefinition.hashCode();
      }
   }


   /**
    * CGLIB callback for filtering method interception behavior.
    */
   private static class MethodOverrideCallbackFilter extends CglibIdentitySupport implements CallbackFilter {

      private static final Log logger = LogFactory.getLog(MethodOverrideCallbackFilter.class);

      public MethodOverrideCallbackFilter(RootBeanDefinition beanDefinition) {
         super(beanDefinition);
      }

      @Override
      public int accept(Method method) {
         // 根据beanDefinition的相关配置加载到MEthodOverrides集合中
         MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method);
         if (logger.isTraceEnabled()) {
            logger.trace("MethodOverride for " + method + ": " + methodOverride);
         }
         if (methodOverride == null) {
            return PASSTHROUGH;
         }
         else if (methodOverride instanceof LookupOverride) {
            return LOOKUP_OVERRIDE;
         }
         else if (methodOverride instanceof ReplaceOverride) {
            return METHOD_REPLACER;
         }
         throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
               methodOverride.getClass().getName());
      }
   }


   /**
    * CGLIB MethodInterceptor to override methods, replacing them with an
    * implementation that returns a bean looked up in the container.
    */
   private static class LookupOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {

      private final BeanFactory owner;

      public LookupOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
         super(beanDefinition);
         this.owner = owner;
      }

      @Override
      public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
         // Cast is safe, as CallbackFilter filters are used selectively.
         LookupOverride lo = (LookupOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
         Assert.state(lo != null, "LookupOverride not found");
         Object[] argsToUse = (args.length > 0 ? args : null);  // if no-arg, don't insist on args at all
         if (StringUtils.hasText(lo.getBeanName())) {
            return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
                  this.owner.getBean(lo.getBeanName()));
         }
         else {
            return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
                  this.owner.getBean(method.getReturnType()));
         }
      }
   }


   /**
    * CGLIB MethodInterceptor to override methods, replacing them with a call
    * to a generic MethodReplacer.
    */
   private static class ReplaceOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {

      private final BeanFactory owner;

      public ReplaceOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
         super(beanDefinition);
         this.owner = owner;
      }

      @Override
      public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
         ReplaceOverride ro = (ReplaceOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
         Assert.state(ro != null, "ReplaceOverride not found");
         // TODO could cache if a singleton for minor performance optimization
         MethodReplacer mr = this.owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class);
         return mr.reimplement(obj, method, args);
      }
   }

}