国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring源碼】講講Bean的生命周期

這篇具有很好參考價值的文章主要介紹了【Spring源碼】講講Bean的生命周期。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1、前言

面試官:“看過Spring源碼吧,簡單說說Spring中Bean的生命周期”

大神仙:“基本生命周期會經(jīng)歷實例化 -> 屬性賦值 -> 初始化 -> 銷毀”。

面試官:“......”

2、Bean的生命周期

如果是普通Bean的生命周期,那么上述的回答是真正確的。確實會經(jīng)歷“實例化 -> 屬性賦值 -> 初始化 -> 銷毀”四個階段。但是請時刻記住,Spring是個框架,框架的特性除了封裝以外,還應當具備擴展性。因此,Spring Bean的生命周期除了上述常見的4個階段外,還應該具體了解每個階段的擴展能力,以及Spring提供的一些擴展機制。

簡單的說可以分為以下幾步:

  1. 對象通過反射機制實例化;執(zhí)行createBeanInstance方法;
  2. 通過populateBean設置屬性,同時會檢查aware接口,設置容器對象屬性;
  3. 初始化,檢查beanPostProcessor擴展前置處理操作;
  4. 如果有init-method方法,執(zhí)行初始化操作;
  5. 執(zhí)行beanPostProcessor擴展后置處理操作;
  6. 注冊到IoC容器中,交由Spring管理;
  7. 對象使用;
  8. 對象銷毀;

整個生命周期管理可以查看Spring源碼:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean。

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
 * <p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 * @param beanName the name of the bean
 * @param mbd the merged bean definition for the bean
 * @param args explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 * @throws BeanCreationException if the bean could not be created
 * @see #instantiateBean
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   ...
   if (instanceWrapper == null) {
      //創(chuàng)建實例,使用工廠方法,構(gòu)造函數(shù)主動注入、簡單初始化
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   ...
   // 中間還有一些循環(huán)依賴的檢測

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // 屬性賦值 
      populateBean(beanName, mbd, instanceWrapper);
      // 初始化
      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);
      }
   }

   ...
   
   // Register bean as disposable.
    try {
        // 注冊bean對象,方便后續(xù)在容器銷毀的時候銷毀對象
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

   return exposedObject;
}

2.1、圖解生命周期

【Spring源碼】講講Bean的生命周期

2.2、createBeanInstance()

對象實例化,我們從源碼org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中,找到createBeanInstance方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

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

   // 判斷當前beanDefinition中是否包含擴展回調(diào)方法,這里是生成bean的第一個策略
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   // 判斷是否有工廠方法初始化策略
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // Shortcut when re-creating the same bean...
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      // 因為一個類可能由多個構(gòu)造函數(shù),所以需要根據(jù)配置文件中配置的參數(shù)或傳入的參數(shù)來確定最終調(diào)用的構(gòu)造函數(shù)。
      // 因為判斷過程會比較,所以spring會將解析、確定好的構(gòu)造函數(shù)緩存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
      // 在下次創(chuàng)建相同時直接從RootBeanDefinition中的屬性resolvedConstructorOrFactoryMethod緩存的值獲取,避免再次解析
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      if (autowireNecessary) {
          // 使用有參構(gòu)造
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
          // 使用默認構(gòu)造函數(shù)
         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.
   // 使用默認的無參構(gòu)造函數(shù)創(chuàng)建對象,如果沒有午餐構(gòu)造,且存在多個有參構(gòu)造且沒有@Autowired注解構(gòu)造,就會直接報錯
   return instantiateBean(beanName, mbd);
}

該方法里面包含了幾種創(chuàng)建bean的策略。如實現(xiàn)FactoryBean方式,supplier方式,反射等等。該階段主要完成了bean對象的實例化操作,此時的bean只是在堆中申請了內(nèi)存,并未進行真正的賦值。

2.3、populateBean()

該階段,為具體的屬性賦值操作。一個對象屬性大致可以分為兩類:

如一個類:

class Person {
    String name;   // 自定義屬性
    BeanFactory beanFactory;  // 容器(IoC容器)屬性
}

屬性賦值的順序為:自定義屬性 -> 容器對象屬性。而容器對象屬性,為一系列實現(xiàn)Aware接口的處理邏輯。典型的如:BeanFactoryAware,ApplicationContextAware等

可以看下populateBean源碼:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   if (bw == null) {
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   // 這里會獲取BeanPostProcessor的擴展處理器。用戶屬性填充的前置后置處理操作。
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
         if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   // 根據(jù)bean的依賴注入方式:即是否標注有 @Autowired 注解或 autowire=“byType/byName” 的標簽
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
          // 根據(jù)名稱進行注入
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
          // 根據(jù)類型進行注入
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
         PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            if (filteredPds == null) {
               filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               return;
            }
         }
         pvs = pvsToUse;
      }
   }
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }

   if (pvs != null) {
       // 自定義屬性填充
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

整個的處理邏輯簡單理解為:

  1. bean對象判空處理
  2. 通過BeanPostprocessor擴展,在屬性注入前最后一次修改bean的屬性值;
  3. 根據(jù)Bean的注入方式,byName或byType完成注入;
  4. 檢測如果有實現(xiàn)Aware接口的bean,進行容器對象屬性賦值;
  5. 將所有的propertyValues?屬性填充到BeanWrapper;

2.4、initializeBean()

上面createBeanInstance() 完成了bean的實例化操作,populateBean()則完成了所有屬性的填充操作。而initializeBean()則是完成最終的初始化操作。

看源碼:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
       // 如果bean實現(xiàn)了 Aware、BeanClassLoaderAware、BeanFactoryAware 的處理
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
       // 調(diào)用bean的后置處理器
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
       // 調(diào)用init初始化方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

invokeAwareMethods:

private void invokeAwareMethods(String beanName, 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);
      }
   }
}

invokeInitMethods:這里便是我們常見的init-methods。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

之所以這里提供了Aware接口實現(xiàn),是用于讓bean擁有某些額外的感知能力。

比如我們自定義的bean里面要擁有BeanFactory或ApplicationContext能力,只需要實現(xiàn)BeanFactoryAware或者ApplicationContextAware即可。

2.5、addSingleton()

到這里,基本上整個Bean的創(chuàng)建,屬性填充,初始化工作都已經(jīng)完成,接下來就需要將該Bean交由IoC容器管理。

具體的實現(xiàn)邏輯,看源碼org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton:

/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
   synchronized (this.singletonObjects) {
       // 將映射關(guān)系添加到單例對象緩存中
      this.singletonObjects.put(beanName, singletonObject);
      // 移除beanName在單例工廠緩存中的數(shù)據(jù)
      this.singletonFactories.remove(beanName);
      // 移除beanName在早期單例工廠緩存中的數(shù)據(jù)
      this.earlySingletonObjects.remove(beanName);
      // 將beanName添加到已注冊的單例集合中
      this.registeredSingletons.add(beanName);
   }
}

這里便將我們上述創(chuàng)建好的bean交由IoC容器管理。隨后便是程序?qū)τ赽ean的使用,以及最終銷毀交由GC回收。

到此,整個bean的生命周期便完整結(jié)束。

3、BeanDefinition

整個Bean的生命周期流程雖然完整結(jié)束,但是從整個源碼看下來,很經(jīng)??吹綄崿F(xiàn)邏輯里面會涉及到兩個很重要的類。BeanDefinition和BeanPostProcessor。

先來說BeanDefinition。是定義Bean的配置元信息的接口,其中包含了一個bean的定義屬性,如類名,作用域,是否懶加載,構(gòu)造參數(shù),是否單例等等定義信息。

4、BeanPostProcessor

BeanPostProcessor是Spring框架提供的擴展接口之一。Spring的擴展能力非常強大,其中一個擴展能力就是我們在整個Bean生命周期的實例化和初始化節(jié)點,可以自己定義一些擴展以實現(xiàn)自己的處理邏輯。比如很常見的AOP實現(xiàn)就是如此。

BeanPostProcessor作為bean處理器的頂級接口,定義了兩個方法:

public interface BeanPostProcessor {

   // 前置初始化操作
   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

  // 后置初始化操作
   @Nullable
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

由方法名字也可以看出,前者在實例化及依賴注入完成后、在任何初始化代碼(比如配置文件中的init-method)調(diào)用之前調(diào)用;后者在初始化代碼調(diào)用之后調(diào)用。此處需要注意的是:接口中的兩個方法都要將傳入的 bean 返回,而不能返回 null,如果返回的是 null 那么我們通過 getBean() 方法將得不到目標。

Spring有兩個核心的功能:IOC和AOP。其中AOP便是依賴于此擴展實現(xiàn)。

我們知道AOP的實現(xiàn)邏輯為代理模式,我們可以觀察一下AOP實現(xiàn)的部分代碼:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
      implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    // 前置處理器
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
       Object cacheKey = getCacheKey(beanClass, beanName);
    
       ...
    
       // Create proxy here if we have a custom TargetSource.
       // Suppresses unnecessary default instantiation of the target bean:
       // The TargetSource will handle target instances in a custom fashion.
       TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
       if (targetSource != null) {
          if (StringUtils.hasLength(beanName)) {
             this.targetSourcedBeans.add(beanName);
          }
          Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
          // 創(chuàng)建代理類
          Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
          this.proxyTypes.put(cacheKey, proxy.getClass());
          return proxy;
       }
    
       return null;
    }
    
    // 后置處理器
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
       if (bean != null) {
          Object cacheKey = getCacheKey(bean.getClass(), beanName);
          if (this.earlyProxyReferences.remove(cacheKey) != bean) {
             return wrapIfNecessary(bean, beanName, cacheKey);
          }
       }
       return bean;
    }
}

我們可以看到前置處理器中有createProxy()方法,基本可以斷定整個的AOP代理類應該是在這里生成,繼續(xù)往下看:

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()) {
      // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
      if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
         // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
         for (Class<?> ifc : beanClass.getInterfaces()) {
            proxyFactory.addInterface(ifc);
         }
      }
   }
   else {
      // No proxyTargetClass flag enforced, let's apply our default checks...
      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);
   }

   // Use original ClassLoader if bean class not locally loaded in overriding class loader
   ClassLoader classLoader = getProxyClassLoader();
   if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
   }
   return proxyFactory.getProxy(classLoader);
}

繼續(xù)看proxyFactory.getProxy(classLoader):

/**
 * Create a new proxy according to the settings in this factory.
 * <p>Can be called repeatedly. Effect will vary if we've added
 * or removed interfaces. Can add and remove interceptors.
 * <p>Uses the given class loader (if necessary for proxy creation).
 * @param classLoader the class loader to create the proxy with
 * (or {@code null} for the low-level proxy facility's default)
 * @return the proxy object
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

繼續(xù)看createAopProxy().getProxy(classLoader):

/**
 * Subclasses should call this to get a new AOP proxy. They should <b>not</b>
 * create an AOP proxy with {@code this} as an argument.
 */
protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}

我們可以看到這里創(chuàng)建了AOP代理對象,返回了AopProxy實例。我們來看下AopProxy發(fā)現(xiàn)是個接口,看一下他的實現(xiàn):

【Spring源碼】講講Bean的生命周期

便是我們熟知的Cglib代理實現(xiàn)和Jdk代理實現(xiàn)方式。

所以到此我們借用AOP的實現(xiàn),了解了BeanPostProcessor的作用,可以更好的幫我們理解和消化整個Bean的生命周期。

5、動手驗證

5.1、創(chuàng)建一個BeanCycleEntity

該實體類實現(xiàn)了aware接口,以及init和destroybean。

package bean.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * @author Shamee loop
 * @date 2023/4/1
 */
@Component
public class BeanCycleEntity implements BeanFactoryAware, InitializingBean, DisposableBean {

    private String name;
    private BeanFactory beanFactory;

    public BeanCycleEntity() {
        System.out.println("【構(gòu)造器】加載BeanCycleEntity的構(gòu)造器實例化");
    }

    public void setName(String name) {
        System.out.println("【屬性注入】加載setName方法注入屬性");
        this.name = name;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【BeanFactoryAware接口】調(diào)用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = beanFactory;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean接口】調(diào)用DiposibleBean.destory()");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】調(diào)用InitializingBean.afterPropertiesSet()");
    }

    public void initMethod(){
        System.out.println("【init-method】調(diào)用<bean>的init-method屬性指定的初始化方法");
    }

    public void destroyMethod() {
        System.out.println("【destroy-method】調(diào)用<bean>的destroy-method屬性指定的初始化方法");
    }

    @Override
    public String toString() {
        System.out.println("【toString】,加載實體類tostring方法");
        return "bean.cycle.BeanCycleEntity{" +
                "name='" + name + '\'' +
                ", beanFactory=" + beanFactory +
                '}';
    }
}

5.2、定義BeanCyclePostProcessor

package bean.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * @author Shamee loop
 * @date 2023/4/1
 */
@Component
public class BeanCyclePostProcessor implements BeanPostProcessor {

    public BeanCyclePostProcessor() {
        super();
        System.out.println("【BeanPostProcessor接口】加載BeanCyclePostProcessor構(gòu)造");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】調(diào)用postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】調(diào)用postProcessAfterInitialization");
        return bean;
    }
}

5.3、定義Aware接口實現(xiàn)

package bean.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * @author Shamee loop
 * @date 2023/4/1
 */
@Component
public class BeanCycleAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
    public BeanCycleAwareBeanPostProcessor() {
        System.out.println("【SmartInstantiationAwareBeanPostProcessor接口】加載BeanCycleAwareBeanPostProcessor構(gòu)造器");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【SmartInstantiationAwareBeanPostProcessor接口】加載postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【SmartInstantiationAwareBeanPostProcessor接口】postProcessAfterInitialization");
        return bean;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("【SmartInstantiationAwareBeanPostProcessor接口】postProcessProperties");
        return pvs;
    }
}

5.4、配置xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <bean id="BeanCycleEntity" class="bean.cycle.BeanCycleEntity" init-method="initMethod"
          destroy-method="destroyMethod" scope="singleton" p:name="張三" />

</beans>

5.5、測試類

package bean.cycle;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Shamee loop
 * @date 2023/4/1
 */
public class BeanCycleDemo {

    public static void main(String[] args) {
        ApplicationContext factory = new ClassPathXmlApplicationContext("bean.xml");
        System.out.println("容器初始化成功");
        BeanCycleEntity beanCycleEntity = factory.getBean(BeanCycleEntity.class);
        System.out.println(beanCycleEntity);

        System.out.println("現(xiàn)在開始關(guān)閉容器!");
        ((ClassPathXmlApplicationContext)factory).registerShutdownHook();
    }
}

5.6、執(zhí)行結(jié)果

【Spring源碼】講講Bean的生命周期

構(gòu)造器實例化 -> 自定義屬性填充 -> aware接口實現(xiàn)填充容器對象屬性 -> 初始化afterPropertiesSet -> 調(diào)用init-method等初始化 -> 初始化成功 -> 銷毀。

6、小結(jié)

整個Spring Bean對象的生命周期,其實說簡單也簡單,說復雜也復雜。簡單是因為不論如何整個bean都逃不開JVM的生命周期,即”創(chuàng)建->初始化->使用->銷毀“四個階段。說復雜是因為Spring對每個節(jié)點都做了很多的邏輯處理,并提供了相當豐富的擴展。不過正是如此豐富的擴展能力,才讓Spring框架如此的強大和靈活。學習Spring Bean生命周期,可以幫助我們更好的去分析當下bean的一個狀態(tài)以及問題的定位。文章來源地址http://www.zghlxwxcb.cn/news/detail-407413.html

到了這里,關(guān)于【Spring源碼】講講Bean的生命周期的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Spring之Bean生命周期源碼解析

    Spring之Bean生命周期源碼解析

    ClassPathBeanDefinitionScanner.java ClassPathScanningCandidateComponentProvider.java 通過組件索引尋找 這里的 componentsIndex 在初始化的時候會嘗試解析 META-INF/spring.components 文件中的配置信息 把斷點打在 ClassPathScanningCandidateComponentProvider 的 setResourceLoader 方法上調(diào)試可以看到堆棧 可以看到,的確

    2024年02月11日
    瀏覽(29)
  • Spring源碼:bean的生命周期(一)

    Spring源碼:bean的生命周期(一)

    本節(jié)將正式介紹Spring源碼細節(jié),將講解Bean生命周期。請注意,雖然我們不希望過于繁瑣地理解Spring源碼,但也不要認為Spring源碼很簡單。在本節(jié)中,我們將主要講解Spring 5.3.10版本的源代碼。如果您看到的代碼與我講解的不同,也沒有關(guān)系,因為其中的原理和業(yè)務邏輯基本相

    2024年02月02日
    瀏覽(23)
  • Spring源碼:Bean的生命周期(二)

    讓我們繼續(xù)講解Spring的Bean實例化過程。在上一節(jié)中,我們已經(jīng)講解了Spring是如何將Bean定義加入到IoC容器中,并使用合并的Bean定義來包裝原始的Bean定義。接下來,我們將繼續(xù)講解Spring的 getBean() 方法,特別是針對 FactoryBean 的解析。 在 getBean() 方法中,Spring還支持對 FactoryBea

    2024年02月02日
    瀏覽(34)
  • 【Spring】Spring之Bean生命周期源碼解析

    什么是bean的生命周期 是指bean在spring中是如何生成,如何銷毀的; spring創(chuàng)建對象的過程,就是IOC(控制反轉(zhuǎn))的過程; JFR Java Flight Record,java飛行記錄,類似于飛機的黑匣子,是JVM內(nèi)置的基于事件的JDK監(jiān)控記錄框架,主要用于問題定位和持續(xù)監(jiān)控; 入口代碼: Spring啟動的時

    2024年02月15日
    瀏覽(23)
  • 【框架源碼】Spring源碼解析之Bean生命周期流程

    【框架源碼】Spring源碼解析之Bean生命周期流程

    觀看本文前,我們先思考一個問題,什么是Spring的bean的生命周期?這也是我們在面試的時候,面試官常問的一個問題。 在沒有Spring之前,我們創(chuàng)建對象的時候,采用new的方式,當對象不在被使用的時候,由Java的垃圾回收機制回收。 而 Spring 中的對象是 bean,bean 和普通的 J

    2024年02月09日
    瀏覽(21)
  • 【深入Spring源碼解析:解密Bean的生命周期】

    Spring是Java企業(yè)級應用開發(fā)領(lǐng)域的一顆明星,它提供了很多方便開發(fā)人員的工具和思想。在分布式系統(tǒng)中,Spring的分布式遠程協(xié)作方案,比如REST、Web服務以及消息傳遞等,也是不可或缺的。 你知道嗎?在我們使用Spring時,容器中存放的所有對象,在Spring啟動的時候就完成了實

    2024年02月05日
    瀏覽(28)
  • 一文讀懂 Spring Bean 的生命周期,unity高級工程師面試題

    一文讀懂 Spring Bean 的生命周期,unity高級工程師面試題

    實例化 該對象不再被使用時通過垃圾回收機制進行回收 而對于 Spring Bean 的生命周期來說: 實例化 Instantiation 屬性賦值 Populate 初始化 Initialization 銷毀 Destruction 實例化 - 屬性賦值 - 初始化 - 銷毀 只有四個步驟,這樣拆解的話是不是感覺也不難?不像其他人寫的那樣直接一上

    2024年04月09日
    瀏覽(48)
  • 【Spring專題】Spring之Bean的生命周期源碼解析——上(掃描生成BeanDefinition)

    【Spring專題】Spring之Bean的生命周期源碼解析——上(掃描生成BeanDefinition)

    由于Spring源碼分析是一個前后聯(lián)系比較強的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識的情況下,大概率沒辦法看懂當前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序): Spring底層核心原理解析——引導篇【學習難度: ★★☆☆☆ 】

    2024年02月13日
    瀏覽(22)
  • 【Spring專題】Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)

    【Spring專題】Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)

    由于Spring源碼分析是一個前后聯(lián)系比較強的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識的情況下,大概率沒辦法看懂當前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序): Spring底層核心原理解析——引導篇【學習難度: ★★☆☆☆ 】

    2024年02月13日
    瀏覽(24)
  • 【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實例化)

    【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實例化)

    由于Spring源碼分析是一個前后聯(lián)系比較強的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識的情況下,大概率沒辦法看懂當前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序): Spring底層核心原理解析——引導篇【學習難度: ★★☆☆☆ 】

    2024年02月13日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包