天天看點

spring-bean生命周期

spring-bean生命周期

文章目錄

  • ​​spring-bean生命周期​​
  • ​​一,整體流程​​
  • ​​二,Bean建立的過程​​
  • ​​2.1 bean執行個體化時機​​
  • ​​2.2 bean生命周期​​
  • ​​2.3 bean循環依賴​​
  • ​​2.4 bean執行個體化過程​​
  • ​​2.5 代理對象生成​​

一,整體流程

spring-bean生命周期

二,Bean建立的過程

2.1 bean執行個體化時機

bean執行個體化時機分為兩類情況:

  • 如果使用​

    ​BeanFactory​

    ​​來執行個體化​

    ​bean​

    ​​,那麼所有的​

    ​bean​

    ​​都是在第一次使用該​

    ​bean​

    ​的時候執行個體化
  • 如果使用​

    ​ApplicationContext​

    ​​來執行個體化​

    ​bean​

  • ​bean​

    ​​的​

    ​scope​

    ​​是​

    ​singleton​

    ​​,且​

    ​lazy-init = false​

    ​時,則在IOC容器啟動初始化時去執行個體化
  • ​bean​

    ​​的​

    ​scope​

    ​​是​

    ​singleton​

    ​​,且​

    ​lazy-init = true​

    ​​時,則在第一次使用該​

    ​bean​

    ​時才去執行個體化
  • ​bean​

    ​​的​

    ​scope​

    ​​是​

    ​prototype​

    ​​,則在第一次使用該​

    ​bean​

    ​時才去執行個體化

Spring 隻幫我們管理單例模式 Bean 的完整生命周期,對于 prototype 的 bean ,Spring 在建立好交給使用者之後則不會再管理後續的生命周期。

2.2 bean生命周期

Bean的執行個體化主要分為三步:

  • 建立bean執行個體
  • bean屬性注入
  • bean初始化
spring-bean生命周期

細化:

  • bean執行個體建立
  • bean屬性注入
  • 檢查是否有實作​

    ​Aware​

    ​接口
  • ​BeanNameAware​

    ​:實作BeanNameAware清主要是為了通過Bean的引用來獲得Bean的ID,一般業務中是很少有用到Bean的ID的
  • ​BeanFactoryAware​

    ​:實作BeanFactoryAware 主要目的是為了擷取Spring容器,如Bean通過Spring容器釋出事件等
  • ​ApplicationContextAwaer​

    ​:作用與BeanFactory類似都是為了擷取Spring容器,不同的是Spring容器在調用setApplicationContext方法時會把它自己作為setApplicationContext 的參數傳入,而Spring容器在調用setBeanDactory前需要程式員自己指定(注入)setBeanDactory裡的參數BeanFactory
  • 檢查是否有實作​

    ​BeanPostProcess​

    ​接口
  • 如果實作,則在初始化前後都會調用相關方法進行增強
  • 檢查是否有自定義初始化方法并且完成bean初始化
  • 使用bean
  • 檢查是否有自定義銷毀方法并且完成銷毀bean

2.3 bean循環依賴

何為循環依賴?
spring-bean生命周期
如何解決?

spring通過三級緩存(三個map)解決了循環依賴這個問題,三級緩存的理論是java基于引用傳遞,當我們擷取到對象的引用時,對象的屬性和字段是可以稍後設定的。三級緩存說白了,就是提前暴露bean引用 + 緩存不同階段的bean

/** 一級緩存:用于存放完全初始化好的 bean **/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** 二級緩存:存放原始的 bean 對象(尚未填充屬性),用于解決循環依賴 */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

/** 三級級緩存:維護建立中Bean的ObjectFactory(解決循環依賴的關鍵) */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);      

檢測循環依賴的過程如下:

  • A 建立過程中需要 B,于是A 将自己放到三級緩裡面,去執行個體化 B
  • B 執行個體化的時候發現需要 A,于是 B 先查一級緩存,沒有,再查二級緩存,還是沒有,再查三級緩存,找到了!
  • 然後把三級緩存裡面的這個 A 放到二級緩存裡面,并删除三級緩存裡面的 A
  • B 順利初始化完畢,将自己放到一級緩存裡面(此時B裡面的A依然是建立中狀态)
  • 然後回來接着建立 A,此時 B 已經建立結束,直接從一級緩存裡面拿到 B ,然後完成建立,并将自己放到一級緩存裡面
  • 如此一來便解決了循環依賴的問題
spring-bean生命周期
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 1. 嘗試去一級緩存中加載我們的bean,IOC容器初始化加載單例bean的時候,第一次進來都會傳回null,一級緩存儲存的已經處理完成的對象
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                // 2. 一級緩存找不到從二級緩存中查找
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    // 3. 二級緩存中找不到去三級緩存中查
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        // 擷取的還沒執行個體化完成的單例bean會被放入二級緩存
                        this.earlySingletonObjects.put(beanName, singletonObject);        
                        // 移除三級緩存中指定的bean
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject;
    }


    public boolean isSingletonCurrentlyInCreation(String beanName) {
        return this.singletonsCurrentlyInCreation.contains(beanName);
    }      
單例bean何時放入一級緩存 ----> 執行個體化好的bean才會被放入到一級緩存,放入完成後,删除二級和三級緩存中該bean的緩存
protected void addSingleton(String beanName, Object singletonObject) {
        synchronized(this.singletonObjects) {
            // 加入到單例緩存池中
            this.singletonObjects.put(beanName, singletonObject);
            // 從三級緩存池中移除(針對的不是處理循環依賴的)
            this.singletonFactories.remove(beanName);
            // 從二級緩存中移除(二級緩存中存儲的是還沒對屬性進行指派的bean)
            this.earlySingletonObjects.remove(beanName);
            // 用于儲存已經處理的bean
            this.registeredSingletons.add(beanName);
        }
    }      
何時放入三級緩存?

如果緩存中沒有bean對象,那麼Spring會建立Bean對象,将執行個體化的bean提前曝光,并且加入緩存中。通過三級緩存可以擷取到最終引用位址,這也是為什麼需要三級緩存的原因。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
            // 這個是執行個體化Bean的方法,會調用構造方法,生成一個原始類型的Bean
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
        try {
          applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
          throw new BeanCreationException(mbd.getResourceDescription(), beanName,
              "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
      }
    }

    // 判斷是否滿足提前暴露bean引用,單例 + 允許循環依賴 + 正在建立
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
            // 滿足則将bean加入到三級緩存中
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
            // 屬性注入
      populateBean(beanName, mbd, instanceWrapper);
            // 初始化bean
      exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
        throw (BeanCreationException) ex;
      }
      else {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
    }

    if (earlySingletonExposure) {
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
        if (exposedObject == bean) {
          exposedObject = earlySingletonReference;
        }
        else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
          String[] dependentBeans = getDependentBeans(beanName);
          Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
          for (String dependentBean : dependentBeans) {
            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
              actualDependentBeans.add(dependentBean);
            }
          }
          if (!actualDependentBeans.isEmpty()) {
            throw new BeanCurrentlyInCreationException(beanName,
                "Bean with name '" + beanName + "' has been injected into other beans [" +
                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                "] in its raw version as part of a circular reference, but has eventually been " +
                "wrapped. This means that said other beans do not use the final version of the " +
                "bean. This is often the result of over-eager type matching - consider using " +
                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
          }
        }
      }
    }

    // Register bean as disposable.
    try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
  }      
何時放入二級緩存?
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
          ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
          if (singletonFactory != null) {
                        // 從三級緩存找到相關引用後,将其提升至二級緩存,并且删除三級緩存
            singletonObject = singletonFactory.getObject();
            this.earlySingletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
          }
        }
      }
    }
    return singletonObject;
  }      
為什麼需要二級緩存?

因為在加入三級緩存時,需要調用​

​getEarlyBeanReference​

​方法

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));      

這裡等價于:

addSingletonFactory(beanName, new ObjectFactory() {
        public Object getObject() throws BeansException {
          return getEarlyBeanReference(beanName, mbd, bean);
        }
      });      

是以該方法每次通過工廠去擷取引用,需要周遊所有的後置處理器也是一個複雜耗時的過程,加入二級緩存,将查找後的最終的引用緩存起來,可以提高效率

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    // 需要暴露的引用
        Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            // 周遊所有後置處理器
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
          SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    // 調用各個bean的後置處理器的getEarlyBeanReference
          exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
        }
      }
    }
    return exposedObject;
  }      

第二個原因:使用三級緩存而非二級緩存并不是因為隻有三級緩存才能解決循環引用問題,其實二級緩存同樣也能很好解決循環引用問題。使用三級而非二級緩存并非出于IOC的考慮,而是出于AOP的考慮,即若使用二級緩存,在AOP情形下,注入到其他bean的,不是最終的代理對象,而是原始對象。

上文我們提到過,通過工廠去擷取引用,需要周遊後置處理器,每個處理器還需要調用getEarlyBeanReference,而AOP的後置處理器:AbstractAutoProxyCreator
public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        // 調用後傳回的是指定bean的代理對象
        return this.wrapIfNecessary(bean, beanName, cacheKey);
    }      

​AbstractAutoProxyCreator#getEarlyBeanReference​

​​傳回的是代理對象,是以​

​exposedObject​

​暴露對象也是代理對象而不是原始對象,是以如果隻使用二級緩存,不使用三級緩存的話,注入到其他bean的将是原始對象,而不是代理對象

參考:

​​Spring系列:Spring循環依賴知多少?(不一樣的深度分析)​​

​​曹工說Spring Boot源碼(29)-- Spring 解決循環依賴為什麼使用三級緩存,而不是二級緩存​​

2.4 bean執行個體化過程

接着上面bean循環依賴的處理關于第三級緩存何時放入,繼續聊bean的執行個體化過程,上面在看放入第三級緩存的方法中:​

​doCreateBean​

​其實裡邊就包含了執行個體建立的過程。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 解析bean的class類型
    Class<?> beanClass = resolveBeanClass(mbd, beanName);
    // 確定bean的class是public
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
          "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
    }
    
        // 工廠方法執行個體化
    if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // 一個類可能有多個構造器,是以Spring得根據參數個數、類型确定需要調用的構造器
    // 在使用構造器建立執行個體後,Spring會将解析過後确定下來的構造器或工廠方法儲存在緩存中,避免再次建立相同bean時再次解析
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
          resolved = true;
          autowireNecessary = mbd.constructorArgumentsResolved;
        }
      }
    }
    if (resolved) {
      if (autowireNecessary) {
        return autowireConstructor(beanName, mbd, null, null);
      }
      else {
        return instantiateBean(beanName, mbd);
      }
    }

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
  }      

上面代碼非常長,總體的功能邏輯如下:

  1. 确定參數。
  1. 如果調用getBean方式時傳入的參數不為空,則可以直接使用傳入的參數;
  2. 再嘗試從緩存中擷取參數
  3. 否則,需要解析配置節點時,配置的構造器參數。
  1. **确定構造函數。**根據第一步中确定下來的參數,接下來的任務就是根據參數的個數、類型來确定最終調用的構造函數。首先是根據參數個數比對,把所有構造函數根據參數個數升序排序,再去篩選參數個數比對的構造函數;因為配置檔案中可以通過參數位置索引,也可以通過參數名稱來設定參數值,如
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
      Object beanInstance;
      if (System.getSecurityManager() != null) {
        beanInstance = AccessController.doPrivileged(
            (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
            getAccessControlContext());
      }
      else {
                // instantiate去通過反射去做執行個體化
        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
  }      

最後看到的調用時​

​BeanUtils​

​​中的反射方法完成執行個體化或者通過​

​CGLIB​

​生成代理對象

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
        constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
        if (constructorToUse == null) {
          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 {
      // 使用了lookup-override或者replace-override功能的話,就需要通過動态代理來建立bean
      return instantiateWithMethodInjection(bd, beanName, owner);
    }
  }      

執行個體化​

​bean​

​​是通過​

​BeanUtils​

​​中的方法通過反射執行個體化出​

​Bean​

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
      ReflectionUtils.makeAccessible(ctor);
      if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
        return KotlinDelegate.instantiateClass(ctor, args);
      }
      else {
        Class<?>[] parameterTypes = ctor.getParameterTypes();
        Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
        Object[] argsWithDefaultValues = new Object[args.length];
        for (int i = 0 ; i < args.length; i++) {
          if (args[i] == null) {
            Class<?> parameterType = parameterTypes[i];
            argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
          }
          else {
            argsWithDefaultValues[i] = args[i];
          }
        }
                // 核心就是通過構造器的newInstance
        return ctor.newInstance(argsWithDefaultValues);
      }
    }
    catch (InstantiationException ex) {
      throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    }
    catch (IllegalAccessException ex) {
      throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    }
    catch (IllegalArgumentException ex) {
      throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    }
    catch (InvocationTargetException ex) {
      throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
  }      

​CGLIB​

​生成代理對象

public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
      Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
      Object instance;
      if (ctor == null) {
        instance = BeanUtils.instantiateClass(subclass);
      }
      else {
        try {
          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.
      Factory factory = (Factory) instance;
      factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
          new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
          new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
      return instance;
    }      

整一個調用鍊路:

createBeanInstance 
    |
instantiateBean(beanName, mbd)
        |
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this) 
            |
BeanUtils.instantiateClass(constructorToUse)      

2.5 代理對象生成

spring有非常多的地方都是使用代理的,但是這些什麼使用代理,使用哪種代理,代理是在什麼時候建立的,怎麼運作起效的。

spring的代理建立類都是AbstractAutoProxyCreator的子類,這個抽象類同時又是InstantiationAwareBeanPostProcessor的實作類。

由于它是BeanPostProcessor的實作類,下面的兩個方法就非常重要:

初始化前方法:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
        return null;
      }
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return null;
      }
    }

    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
        this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            // 建立代理對象
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
    }

    return null;
  }      

建立代理:​

​AbstractAutoProxyCreator#createProxy​

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
        proxyFactory.setProxyTargetClass(true);
      }
      else {
        evaluateProxyInterfaces(beanClass, proxyFactory);
      }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
    }
    // 通過代理工廠建立代理
    return proxyFactory.getProxy(getProxyClassLoader());
  }

  public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
  }      

​ProxyFactory#getProxy​

​​他是​

​ProxyCreatorSupport​

​​的子類,​

​ProxyCreatorSupport​

​定義了代理對象的生成方法:

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
      activate();
    }
    return getAopProxyFactory().createAopProxy(this);
  }      

通過代理工廠生産代理​

​AopProxyFactory​

​:

@Override
  public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: " +
            "Either an interface or a target is required for proxy creation.");
      }
            // 如果目标類實作接口則使用JDK動态代理
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
        return new JdkDynamicAopProxy(config);
      }// 否則使用CGLIB實作動态代理
      return new ObjenesisCglibAopProxy(config);
    }
    else {
      return new JdkDynamicAopProxy(config);
    }
  }      

JDK動态代理:

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
    Assert.notNull(config, "AdvisedSupport must not be null");
    if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
      throw new AopConfigException("No advisors and no TargetSource specified");
    }
    this.advised = config;
  }


  @Override
  public Object getProxy() {
    return getProxy(ClassUtils.getDefaultClassLoader());
  }

  @Override
  public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        // 底層還是Proxy對象的newProxyInstance方法
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
  }      

JDK和CGILB動态代理原理補充:

JDK動态代理關鍵實作方法解析:

  1. 調用 getProxyClass0() 方法擷取代理類的 Class 對象
  2. 通過反射生成 代理類的執行個體,并傳回。
public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        
        // 調用 getProxyClass0() 方法擷取代理類的 Class 對象
        Class<?> cl = getProxyClass0(loader, intfs);

        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            // 通過反射生成 代理類的執行個體,并傳回。
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

// 查詢緩存,判斷之前有無實作過該代理類,沒有則通過ProxyClassFactory.apply() 方法生成代理類
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }
    return proxyClassCache.get(loader, interfaces);
}

// proxyClassCache
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());      

生成代理類:

private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // 代理類字首
        private static final String proxyClassNamePrefix = "$Proxy";
        // 用于生成代理類的唯一編号
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            
            // 實作接口集合
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                Class<?> interfaceClass = null;
                interfaceClass = Class.forName(intf.getName(), false, loader);
            }
            // 代理類包名生成
            String proxyPkg = null;     
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }
            // 預設包名
            if (proxyPkg == null) {
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }
            // 代理類名 = 包名 + $Proxy + 唯一編号
            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;
            // 生成代理類的位元組碼檔案
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                // 通過classloader 動态加載 位元組碼,并生成動态代理類的Class執行個體,并傳回
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                throw new IllegalArgumentException(e.toString());
            }
        }
    }      

是以,JDK動态代理是通過生成代理類的位元組碼,然後利用classloader動态加載位元組碼生成動态代理類的class執行個體

繼續閱讀