<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Bean生命周期

          共 11494字,需瀏覽 23分鐘

           ·

          2021-02-20 10:17

          點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時間送達(dá)

          ? 作者?|? Gouden

          來源 |? urlify.cn/2QZr6f

          76套java從入門到精通實戰(zhàn)課程分享

          Spring Bean生命周期整體可分為以下幾個階段:

          • Spring Bean元信息處理階段

          • Spring Bean實例化階段

          • Spring Bean初始化階段

          • Spring Bean銷毀階段

          • Spring Bean垃圾收集階段

          Spring Bean生命周期處理是Spring應(yīng)用上下文生命周期的一部分,可以參考此文了解Spring應(yīng)用上下文生命周期。

          Spring Bean元信息處理階段

          Spring Bean元信息處理階段可以細(xì)分為以下幾個階段:

          • Spring Bean元信息解析階段

          • Spring BeanDefinition注冊階段

          • Spring BeanDefinition合并階段

          Spring Bean元信息解析階段

          在Spring應(yīng)用上下文生命周期里有一個創(chuàng)建BeanFactory階段,在這個階段會創(chuàng)建底層IoC容器BeanFactory,然后會進(jìn)行一些別的操作,其中一個操作就是處理Spring Bean元信息,代碼如下所示:

          protected?final?void?refreshBeanFactory()?throws?BeansException?{
          ????????if?(hasBeanFactory())?{
          ????????????destroyBeans();
          ????????????closeBeanFactory();
          ????????}
          ????????try?{
          ????????????DefaultListableBeanFactory?beanFactory?=?createBeanFactory();
          ????????????beanFactory.setSerializationId(getId());
          ????????????customizeBeanFactory(beanFactory);
          ????????????loadBeanDefinitions(beanFactory);
          ????????????synchronized?(this.beanFactoryMonitor)?{
          ????????????????this.beanFactory?=?beanFactory;
          ????????????}
          ????????}
          ????????catch?(IOException?ex)?{
          ????????????throw?new?ApplicationContextException("I/O?error?parsing?bean?definition?source?for?"?+?getDisplayName(),?ex);
          ????????}
          ????}

          可以看出這個方法會調(diào)用方法loadBeanDefinitions加載Spring Bean元信息: BeanDefinition。

          loadBeanDefinitions在子類AbstractXmlApplicationContext有一個實現(xiàn),代碼如下所示:

          @Override
          ????protected?void?loadBeanDefinitions(DefaultListableBeanFactory?beanFactory)?throws?BeansException,?IOException?{
          ????????//創(chuàng)建XmlBeanDefinitionReader解析XML配置文件讀取Spring?Bean元信息
          ????????XmlBeanDefinitionReader?beanDefinitionReader?=?new?XmlBeanDefinitionReader(beanFactory);

          ????????//設(shè)置Spring?Bean元信息讀取配置
          ????????beanDefinitionReader.setEnvironment(this.getEnvironment());
          ????????beanDefinitionReader.setResourceLoader(this);
          ????????beanDefinitionReader.setEntityResolver(new?ResourceEntityResolver(this));

          ????????//初始化XmlBeanDefinitionReader
          ????????initBeanDefinitionReader(beanDefinitionReader);?????//加載Spring?Bean元信息
          ????????loadBeanDefinitions(beanDefinitionReader);
          ????}
          protected?void?loadBeanDefinitions(XmlBeanDefinitionReader?reader)?throws?BeansException,?IOException?{?????//獲取資源配置
          ????????Resource[]?configResources?=?getConfigResources();?????//如果不是空,加載對應(yīng)資源
          ????????if?(configResources?!=?null)?{
          ????????????reader.loadBeanDefinitions(configResources);
          ????????}?????//獲取資源配置字符串,是路徑
          ????????String[]?configLocations?=?getConfigLocations();?????//如果不是空,加載對應(yīng)資源
          ????????if?(configLocations?!=?null)?{
          ????????????reader.loadBeanDefinitions(configLocations);
          ????????}
          ????}

          這一塊代碼邏輯比較簡單,就是使用XmlBeanDefinitionReader加載Spring Bean元信息,這里指處理了XML配置的元信息。

          還有一種常用Spring Bean元信息配置是注解,針對這種Spring Bean元信息配置的解析,在AnnotationConfigApplicationContext進(jìn)行處理,代碼如下所示:

          ????public?AnnotationConfigApplicationContext(String...?basePackages)?{
          ????????this();
          ????????scan(basePackages);
          ????????refresh();
          ????}

          AnnotationConfigApplicationContext一個構(gòu)造器里會調(diào)用scan方法掃描指定包路徑,會使用ClassPathBeanDefinitionScanner的scan能力掃描具有某些注解的類,把這些類加載為Spring Bean元信息。

          Spring BeanDefinition注冊階段

          上面著重介紹了Spring Bean元信息解析,Spring Bean元信息解析之后,就要注冊并保存起來,方便后續(xù)使用。

          Spring具有一個數(shù)據(jù)結(jié)構(gòu)BeanDefinitionRegistry,解析后的BeanDefinition會注冊到BeanDefinitionRegistry,BeanDefinitionRegistry是一個接口,一個典型的實現(xiàn)類是DefaultListableBeanFactory。

          DefaultListableBeanFactory里的registerBeanDefinition方法實現(xiàn)如下所示(這里刪除了一些打印日志分支):

          public?void?registerBeanDefinition(String?beanName,?BeanDefinition?beanDefinition)
          ????????????throws?BeanDefinitionStoreException?{
          ?????//校驗入?yún)?br>????????Assert.hasText(beanName,?"Bean?name?must?not?be?empty");
          ????????Assert.notNull(beanDefinition,?"BeanDefinition?must?not?be?null");
          ?????????//判斷BeanDefinition是否是AbstractBeanDefinition類或子類的對象,如果是,進(jìn)行校驗
          ????????if?(beanDefinition?instanceof?AbstractBeanDefinition)?{
          ????????????try?{
          ????????????????((AbstractBeanDefinition)?beanDefinition).validate();
          ????????????}
          ????????????catch?(BeanDefinitionValidationException?ex)?{
          ????????????????throw?new?BeanDefinitionStoreException(beanDefinition.getResourceDescription(),?beanName,
          ????????????????????????"Validation?of?bean?definition?failed",?ex);
          ????????????}
          ????????}
          ?????//判斷beanName對應(yīng)BeanDefinition是否存在
          ????????BeanDefinition?existingDefinition?=?this.beanDefinitionMap.get(beanName);?????//如果已經(jīng)存在,判斷是否允許覆蓋,這里覆蓋是指一個beanName有兩個不同BeanDefinition,默認(rèn)允許
          ????????if?(existingDefinition?!=?null)?{????????//如果不允許覆蓋,拋出異常
          ????????????if?(!isAllowBeanDefinitionOverriding())?{
          ????????????????throw?new?BeanDefinitionOverrideException(beanName,?beanDefinition,?existingDefinition);
          ????????????}????????//如果允許覆蓋,覆蓋配置
          ????????????this.beanDefinitionMap.put(beanName,?beanDefinition);
          ????????}
          ????????else?{????????//判斷是否已經(jīng)有Bean被創(chuàng)建了
          ????????????if?(hasBeanCreationStarted())?{
          ????????????????//如果是就不能修改之前集合,需要全量覆蓋
          ????????????????synchronized?(this.beanDefinitionMap)?{
          ????????????????????this.beanDefinitionMap.put(beanName,?beanDefinition);
          ????????????????????List?updatedDefinitions?=?new?ArrayList<>(this.beanDefinitionNames.size()?+?1);
          ????????????????????updatedDefinitions.addAll(this.beanDefinitionNames);
          ????????????????????updatedDefinitions.add(beanName);
          ????????????????????this.beanDefinitionNames?=?updatedDefinitions;
          ????????????????????removeManualSingletonName(beanName);
          ????????????????}
          ????????????}
          ????????????else?{
          ????????????????//如果不是就修改之前集合
          ????????????????this.beanDefinitionMap.put(beanName,?beanDefinition);
          ????????????????this.beanDefinitionNames.add(beanName);
          ????????????????removeManualSingletonName(beanName);
          ????????????}
          ????????????this.frozenBeanDefinitionNames?=?null;
          ????????}
          ?????//判斷是否存在這個配置且已經(jīng)創(chuàng)建單例Bean
          ????????if?(existingDefinition?!=?null?||?containsSingleton(beanName))?{????????//如果是就清除緩存
          ????????????resetBeanDefinition(beanName);
          ????????}
          ????}

          Spring BeanDefinition合并階段

          Spring BeanDefinition在用來實例化前,還需要做的一件事就是Spring BeanDefinition合并。

          在底層IoC容器通常會有兩種BeanDefinition,一個是GenericBeanDefinition,一個是RootBeanDefinition,一個Bean在實例化前,對應(yīng)BeanDefinition都要轉(zhuǎn)化成RootBeanDefinition。

          GenericBeanDefinition保存原始的Spring Bean元信息,可以指定父Bean的beanName,但是不會繼承父Bean的屬性,還不具備實例化的能力。

          GenericBeanDefinition在合并之后會變成RootBeanDefinition,這時RootBeanDefinition不會保存父Bean的beanName,但是會從父Bean繼承屬性。

          就算一個GenericBeanDefinition沒有父Bean也需要轉(zhuǎn)換成RootBeanDefinition。

          BeanDefinition合并操作通常在實例化前進(jìn)行,ConfigurableBeanFactory#getMergedBeanDefinition方法會合并對應(yīng)BeanDefinition并且返回,getMergedBeanDefinition(AbstractBeanFactory)代碼如下所示:

          public?BeanDefinition?getMergedBeanDefinition(String?name)?throws?BeansException?{
          ????????String?beanName?=?transformedBeanName(name);
          ????????//判斷當(dāng)前BeanFactory不存在對應(yīng)BeanDefinition,從父BeanFactory獲取合并后的BeanDefinition
          ????????if?(!containsBeanDefinition(beanName)?&&?getParentBeanFactory()?instanceof?ConfigurableBeanFactory)?{
          ????????????return?((ConfigurableBeanFactory)?getParentBeanFactory()).getMergedBeanDefinition(beanName);
          ????????}
          ????????//從當(dāng)前BeanFactory獲取合并后的BeanDefintion
          ????????return?getMergedLocalBeanDefinition(beanName);
          ????}
          protected?RootBeanDefinition?getMergedLocalBeanDefinition(String?beanName)?throws?BeansException?{
          ????????//從緩存里獲取RootBeanDefinition
          ????????RootBeanDefinition?mbd?=?this.mergedBeanDefinitions.get(beanName);?????//如果不是空并且不需要再次合并,返回緩存的RootBeanDefinition
          ????????if?(mbd?!=?null?&&?!mbd.stale)?{
          ????????????return?mbd;
          ????????}?????//返回合并的BeanDefinition,入?yún)⑹莃eanName、GenericBeanDefinition
          ????????return?getMergedBeanDefinition(beanName,?getBeanDefinition(beanName));
          ????}

          最后會進(jìn)到下面這個方法:

          protected?RootBeanDefinition?getMergedBeanDefinition(
          ????????????String?beanName,?BeanDefinition?bd,?@Nullable?BeanDefinition?containingBd)
          ????????????throws?BeanDefinitionStoreException?{

          ????????synchronized?(this.mergedBeanDefinitions)?{
          ????????????RootBeanDefinition?mbd?=?null;
          ????????????RootBeanDefinition?previous?=?null;

          ????????????//加鎖后再從緩存里查詢一次,dcl
          ????????????if?(containingBd?==?null)?{
          ????????????????mbd?=?this.mergedBeanDefinitions.get(beanName);
          ????????????}
          ????????//如果獲取不到或者需要再次合并,執(zhí)行合并BeanDefinition邏輯
          ????????????if?(mbd?==?null?||?mbd.stale)?{
          ????????????????previous?=?mbd;
          ????????????????if?(bd.getParentName()?==?null)?{
          ????????????????????//如果沒有父beanName,直接生成RootBeanDefinition
          ????????????????????if?(bd?instanceof?RootBeanDefinition)?{
          ????????????????????????mbd?=?((RootBeanDefinition)?bd).cloneBeanDefinition();
          ????????????????????}
          ????????????????????else?{
          ????????????????????????mbd?=?new?RootBeanDefinition(bd);
          ????????????????????}
          ????????????????}
          ????????????????else?{
          ????????????????????//如果有父beanName,需要用父BeanDefinition合并生成RootBeanDefinition
          ????????????????????BeanDefinition?pbd;
          ????????????????????try?{
          ????????????????????????String?parentBeanName?=?transformedBeanName(bd.getParentName());
          ????????????????????????if?(!beanName.equals(parentBeanName))?{?????????????????//用parentBeanName獲取BeanDefinition
          ????????????????????????????pbd?=?getMergedBeanDefinition(parentBeanName);
          ????????????????????????}
          ????????????????????????else?{
          ????????????????????????????BeanFactory?parent?=?getParentBeanFactory();
          ????????????????????????????if?(parent?instanceof?ConfigurableBeanFactory)?{
          ????????????????????????????????pbd?=?((ConfigurableBeanFactory)?parent).getMergedBeanDefinition(parentBeanName);
          ????????????????????????????}
          ????????????????????????????else?{
          ????????????????????????????????throw?new?NoSuchBeanDefinitionException(parentBeanName,
          ????????????????????????????????????????"Parent?name?'"?+?parentBeanName?+?"'?is?equal?to?bean?name?'"?+?beanName?+
          ????????????????????????????????????????"':?cannot?be?resolved?without?an?AbstractBeanFactory?parent");
          ????????????????????????????}
          ????????????????????????}
          ????????????????????}
          ????????????????????catch?(NoSuchBeanDefinitionException?ex)?{
          ????????????????????????throw?new?BeanDefinitionStoreException(bd.getResourceDescription(),?beanName,
          ????????????????????????????????"Could?not?resolve?parent?bean?definition?'"?+?bd.getParentName()?+?"'",?ex);
          ????????????????????}
          ????????????????????//用parentBeanName獲取RootBeanDefinition創(chuàng)建RootBeanDefinition
          ????????????????????mbd?=?new?RootBeanDefinition(pbd);?????????????//用子BeanDefinition覆蓋RootBeanDefinition
          ????????????????????mbd.overrideFrom(bd);
          ????????????????}

          ????????????????//設(shè)置scope
          ????????????????if?(!StringUtils.hasLength(mbd.getScope()))?{
          ????????????????????mbd.setScope(SCOPE_SINGLETON);
          ????????????????}

          ????????????????if?(containingBd?!=?null?&&?!containingBd.isSingleton()?&&?mbd.isSingleton())?{
          ????????????????????mbd.setScope(containingBd.getScope());
          ????????????????}

          ????????????????//把RootBeanDefinition放到緩存
          ????????????????if?(containingBd?==?null?&&?isCacheBeanMetadata())?{
          ????????????????????this.mergedBeanDefinitions.put(beanName,?mbd);
          ????????????????}
          ????????????}
          ????????????if?(previous?!=?null)?{
          ????????????????copyRelevantMergedBeanDefinitionCaches(previous,?mbd);
          ????????????}
          ????????????return?mbd;
          ????????}
          ????}

          Spring Bean實例化階段

          Spring Bean實例化階段可以細(xì)分為以下幾個階段:

          • Spring Bean Class加載階段

          • Spring Bean實例化階段

          • Spring Bean實例化前階段

          • Spring Bean實例化后階段

          • Spring Bean屬性賦值前階段

          • Spring Bean賦值階段

          Spring Bean Class加載階段

          Spring Bean Class加載方法是AbstractBeanFactory#resolveBeanClass,代碼如下所示:

          ?resolveBeanClass方法會使用RootBeanDefinition里記錄的beanClassName加載對應(yīng)類,保存到RootBeanDefinition并且返回。

          protected?Class?resolveBeanClass(final?RootBeanDefinition?mbd,?String?beanName,?final?Class...?typesToMatch)
          ????????????throws?CannotLoadBeanClassException?{

          ????????try?{
          ????????????if?(mbd.hasBeanClass())?{??????????//判斷RootBeanDefinition里關(guān)聯(lián)了class,直接返回
          ????????????????return?mbd.getBeanClass();
          ????????????}
          ????????????if?(System.getSecurityManager()?!=?null)?{??????????//加載對應(yīng)class
          ????????????????return?AccessController.doPrivileged((PrivilegedExceptionAction>)?()?->
          ????????????????????doResolveBeanClass(mbd,?typesToMatch),?getAccessControlContext());
          ????????????}
          ????????????else?{??????????//加載對應(yīng)class
          ????????????????return?doResolveBeanClass(mbd,?typesToMatch);
          ????????????}
          ????????}
          ????????catch?(PrivilegedActionException?pae)?{
          ????????????ClassNotFoundException?ex?=?(ClassNotFoundException)?pae.getException();
          ????????????throw?new?CannotLoadBeanClassException(mbd.getResourceDescription(),?beanName,?mbd.getBeanClassName(),?ex);
          ????????}
          ????????catch?(ClassNotFoundException?ex)?{
          ????????????throw?new?CannotLoadBeanClassException(mbd.getResourceDescription(),?beanName,?mbd.getBeanClassName(),?ex);
          ????????}
          ????????catch?(LinkageError?err)?{
          ????????????throw?new?CannotLoadBeanClassException(mbd.getResourceDescription(),?beanName,?mbd.getBeanClassName(),?err);
          ????????}
          ????}
          private?Class?doResolveBeanClass(RootBeanDefinition?mbd,?Class...?typesToMatch)
          ????????????throws?ClassNotFoundException?{
          ?????//獲取當(dāng)前類加載器
          ????????ClassLoader?beanClassLoader?=?getBeanClassLoader();?????//定義動態(tài)類加載器,默認(rèn)是上面的類加載器,可以修改擴展
          ????????ClassLoader?dynamicLoader?=?beanClassLoader;
          ????????boolean?freshResolve?=?false;

          ????????if?(!ObjectUtils.isEmpty(typesToMatch))?{
          ????????????//如果tempClassLoader不是空,動態(tài)類加載器設(shè)置為tempClassLoader
          ????????????ClassLoader?tempClassLoader?=?getTempClassLoader();
          ????????????if?(tempClassLoader?!=?null)?{
          ????????????????dynamicLoader?=?tempClassLoader;
          ????????????????freshResolve?=?true;
          ????????????????if?(tempClassLoader?instanceof?DecoratingClassLoader)?{
          ????????????????????DecoratingClassLoader?dcl?=?(DecoratingClassLoader)?tempClassLoader;
          ????????????????????for?(Class?typeToMatch?:?typesToMatch)?{
          ????????????????????????dcl.excludeClass(typeToMatch.getName());
          ????????????????????}
          ????????????????}
          ????????????}
          ????????}

          ????????String?className?=?mbd.getBeanClassName();
          ????????if?(className?!=?null)?{
          ????????????Object?evaluated?=?evaluateBeanDefinitionString(className,?mbd);
          ????????????if?(!className.equals(evaluated))?{
          ????????????????//如果evaluateBeanDefinitionString
          ????????????????if?(evaluated?instanceof?Class)?{
          ????????????????????return?(Class)?evaluated;
          ????????????????}
          ????????????????else?if?(evaluated?instanceof?String)?{
          ????????????????????className?=?(String)?evaluated;
          ????????????????????freshResolve?=?true;
          ????????????????}
          ????????????????else?{
          ????????????????????throw?new?IllegalStateException("Invalid?class?name?expression?result:?"?+?evaluated);
          ????????????????}
          ????????????}
          ????????????if?(freshResolve)?{
          ????????????????//使用dynamicLoader加載class并且不和RootBeanDefinition關(guān)聯(lián),目前沒有用到過,后面確認(rèn)用處
          ????????????????if?(dynamicLoader?!=?null)?{
          ????????????????????try?{
          ????????????????????????return?dynamicLoader.loadClass(className);
          ????????????????????}
          ????????????????????catch?(ClassNotFoundException?ex)?{
          ????????????????????????if?(logger.isTraceEnabled())?{
          ????????????????????????????logger.trace("Could?not?load?class?["?+?className?+?"]?from?"?+?dynamicLoader?+?":?"?+?ex);
          ????????????????????????}
          ????????????????????}
          ????????????????}
          ????????????????return?ClassUtils.forName(className,?dynamicLoader);
          ????????????}
          ????????}

          ????????//常規(guī)處理方式,RootBeanDefinition使用默認(rèn)類加載器并且關(guān)聯(lián)到RootBeanDefinition
          ????????return?mbd.resolveBeanClass(beanClassLoader);
          ????}

          Spring Bean實例化階段

          AbstractAutowireCapableBeanFactory#createBeanInstance方法處理Spring Bean實例化,給指定beanName創(chuàng)建一個新的實例,先后使用工廠方法、構(gòu)造器自動注入、簡單實例化方式創(chuàng)建,具體代碼如下所示:?

          protected?BeanWrapper?createBeanInstance(String?beanName,?RootBeanDefinition?mbd,?@Nullable?Object[]?args)?{
          ????????//使用RootBeanDefinition加載class
          ????????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());
          ????????}
          ?????//配置lamda方式實例化Bean
          ????????Supplier?instanceSupplier?=?mbd.getInstanceSupplier();
          ????????if?(instanceSupplier?!=?null)?{
          ????????????return?obtainFromSupplier(instanceSupplier,?beanName);
          ????????}
          ?????//如果是工廠方式,用工廠方式實例化對象
          ????????if?(mbd.getFactoryMethodName()?!=?null)?{
          ????????????return?instantiateUsingFactoryMethod(beanName,?mbd,?args);
          ????????}

          ????????//如果某個RootBeanDefinition已經(jīng)實例化過再次實例化,直接使用上次配置,不需要再決策
          ????????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);
          ????????????}
          ????????}

          ????????//決策候選構(gòu)造器
          ????????Constructor[]?ctors?=?determineConstructorsFromBeanPostProcessors(beanClass,?beanName);
          ????????if?(ctors?!=?null?||?mbd.getResolvedAutowireMode()?==?AUTOWIRE_CONSTRUCTOR?||
          ????????????????mbd.hasConstructorArgumentValues()?||?!ObjectUtils.isEmpty(args))?{
          ????????????return?autowireConstructor(beanName,?mbd,?ctors,?args);
          ????????}

          ????????//獲取合適構(gòu)造器
          ????????ctors?=?mbd.getPreferredConstructors();
          ????????if?(ctors?!=?null)?{
          ????????????return?autowireConstructor(beanName,?mbd,?ctors,?null);
          ????????}

          ????????//使用無參構(gòu)造器實例化對象
          ????????return?instantiateBean(beanName,?mbd);
          ????}

          Spring Bean實例化前階段

          AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation方法提供一個擴展方式可以讓Spring Bean在實例化前做一些擴展,比如一些RPC場景,可以在這里生成RPC接口代理類,不執(zhí)行實例化邏輯,具體代碼如下所示:

          protected?Object?resolveBeforeInstantiation(String?beanName,?RootBeanDefinition?mbd)?{
          ????????Object?bean?=?null;
          ????????if?(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved))?{
          ????????????//如果有InstantiationAwareBeanPostProcessors,調(diào)用applyBeanPostProcessorsBeforeInstantiation方法獲取對象
          ????????????if?(!mbd.isSynthetic()?&&?hasInstantiationAwareBeanPostProcessors())?{
          ????????????????Class?targetType?=?determineTargetType(beanName,?mbd);
          ????????????????if?(targetType?!=?null)?{
          ????????????????????bean?=?applyBeanPostProcessorsBeforeInstantiation(targetType,?beanName);
          ????????????????????if?(bean?!=?null)?{
          ????????????????????????bean?=?applyBeanPostProcessorsAfterInitialization(bean,?beanName);
          ????????????????????}
          ????????????????}
          ????????????}
          ????????????mbd.beforeInstantiationResolved?=?(bean?!=?null);
          ????????}
          ????????return?bean;
          ????}
          protected?Object?applyBeanPostProcessorsBeforeInstantiation(Class?beanClass,?String?beanName)?{
          ????????for?(BeanPostProcessor?bp?:?getBeanPostProcessors())?{
          ????????????if?(bp?instanceof?InstantiationAwareBeanPostProcessor)?{
          ????????????????InstantiationAwareBeanPostProcessor?ibp?=?(InstantiationAwareBeanPostProcessor)?bp;??????????//調(diào)用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法創(chuàng)建對象
          ????????????????Object?result?=?ibp.postProcessBeforeInstantiation(beanClass,?beanName);
          ????????????????if?(result?!=?null)?{
          ????????????????????return?result;
          ????????????????}
          ????????????}
          ????????}
          ????????return?null;
          ????}

          Spring Bean實例化后階段

          AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法是Spring提供的第一個Spring Bean實例化后擴展,實現(xiàn)MergedBeanDefinitionPostProcessor接口即可進(jìn)行擴展,具體代碼如下所示:

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

          Spring提供的第二個實例化后擴展是InstantiationAwareBeanPostProcessor,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代碼處理這個擴展,具體代碼如下所示:

          if?(!mbd.isSynthetic()?&&?hasInstantiationAwareBeanPostProcessors())?{
          ???for?(BeanPostProcessor?bp?:?getBeanPostProcessors())?{
          ??????if?(bp?instanceof?InstantiationAwareBeanPostProcessor)?{
          ?????????InstantiationAwareBeanPostProcessor?ibp?=?(InstantiationAwareBeanPostProcessor)?bp;
          ?????????if?(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),?beanName))?{
          ????????????return;
          ?????????}
          ??????}
          ???}
          }

          Spring Bean賦值前階段

          Spring Bean賦值前提供擴展是InstantiationAwareBeanPostProcessor#postProcessProperties和InstantiationAwareBeanPostProcessor#postProcessPropertyValues,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代碼處理這兩個擴展,具體代碼如下所示:

          if?(hasInstAwareBpps)?{
          ???if?(pvs?==?null)?{
          ??????pvs?=?mbd.getPropertyValues();
          ???}
          ???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;
          ??????}
          ???}
          }

          Spring Bean賦值階段

          Spring Bean賦值階段代碼如下所示:

          protected?void?applyPropertyValues(String?beanName,?BeanDefinition?mbd,?BeanWrapper?bw,?PropertyValues?pvs)?{
          ???if?(pvs.isEmpty())?{
          ??????return;
          ???}

          ???if?(System.getSecurityManager()?!=?null?&&?bw?instanceof?BeanWrapperImpl)?{
          ??????((BeanWrapperImpl)?bw).setSecurityContext(getAccessControlContext());
          ???}

          ???MutablePropertyValues?mpvs?=?null;
          ???List?original;

          ???if?(pvs?instanceof?MutablePropertyValues)?{
          ??????mpvs?=?(MutablePropertyValues)?pvs;
          ??????if?(mpvs.isConverted())?{
          ?????????//?Shortcut:?use?the?pre-converted?values?as-is.
          ?????????try?{
          ????????????bw.setPropertyValues(mpvs);
          ????????????return;
          ?????????}
          ?????????catch?(BeansException?ex)?{
          ????????????throw?new?BeanCreationException(
          ??????????????????mbd.getResourceDescription(),?beanName,?"Error?setting?property?values",?ex);
          ?????????}
          ??????}
          ??????original?=?mpvs.getPropertyValueList();
          ???}
          ???else?{
          ??????original?=?Arrays.asList(pvs.getPropertyValues());
          ???}

          ???TypeConverter?converter?=?getCustomTypeConverter();
          ???if?(converter?==?null)?{
          ??????converter?=?bw;
          ???}
          ???BeanDefinitionValueResolver?valueResolver?=?new?BeanDefinitionValueResolver(this,?beanName,?mbd,?converter);

          ???//?Create?a?deep?copy,?resolving?any?references?for?values.
          ???List?deepCopy?=?new?ArrayList<>(original.size());
          ???boolean?resolveNecessary?=?false;
          ???for?(PropertyValue?pv?:?original)?{
          ??????if?(pv.isConverted())?{
          ?????????deepCopy.add(pv);
          ??????}
          ??????else?{
          ?????????String?propertyName?=?pv.getName();
          ?????????Object?originalValue?=?pv.getValue();
          ?????????if?(originalValue?==?AutowiredPropertyMarker.INSTANCE)?{
          ????????????Method?writeMethod?=?bw.getPropertyDescriptor(propertyName).getWriteMethod();
          ????????????if?(writeMethod?==?null)?{
          ???????????????throw?new?IllegalArgumentException("Autowire?marker?for?property?without?write?method:?"?+?pv);
          ????????????}
          ????????????originalValue?=?new?DependencyDescriptor(new?MethodParameter(writeMethod,?0),?true);
          ?????????}
          ?????????Object?resolvedValue?=?valueResolver.resolveValueIfNecessary(pv,?originalValue);
          ?????????Object?convertedValue?=?resolvedValue;
          ?????????boolean?convertible?=?bw.isWritableProperty(propertyName)?&&
          ???????????????!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
          ?????????if?(convertible)?{
          ????????????convertedValue?=?convertForProperty(resolvedValue,?propertyName,?bw,?converter);
          ?????????}
          ?????????//?Possibly?store?converted?value?in?merged?bean?definition,
          ?????????//?in?order?to?avoid?re-conversion?for?every?created?bean?instance.
          ?????????if?(resolvedValue?==?originalValue)?{
          ????????????if?(convertible)?{
          ???????????????pv.setConvertedValue(convertedValue);
          ????????????}
          ????????????deepCopy.add(pv);
          ?????????}
          ?????????else?if?(convertible?&&?originalValue?instanceof?TypedStringValue?&&
          ???????????????!((TypedStringValue)?originalValue).isDynamic()?&&
          ???????????????!(convertedValue?instanceof?Collection?||?ObjectUtils.isArray(convertedValue)))?{
          ????????????pv.setConvertedValue(convertedValue);
          ????????????deepCopy.add(pv);
          ?????????}
          ?????????else?{
          ????????????resolveNecessary?=?true;
          ????????????deepCopy.add(new?PropertyValue(pv,?convertedValue));
          ?????????}
          ??????}
          ???}
          ???if?(mpvs?!=?null?&&?!resolveNecessary)?{
          ??????mpvs.setConverted();
          ???}

          ???//?Set?our?(possibly?massaged)?deep?copy.
          ???try?{
          ??????bw.setPropertyValues(new?MutablePropertyValues(deepCopy));
          ???}
          ???catch?(BeansException?ex)?{
          ??????throw?new?BeanCreationException(
          ????????????mbd.getResourceDescription(),?beanName,?"Error?setting?property?values",?ex);
          ???}
          }

          Spring Bean初始化階段

          Spring Bean初始化階段可以細(xì)分為以下幾個階段:

          • Spring Bean Aware接口回調(diào)階段

          • Spring Bean初始化前階段

          • Spring Bean初始化階段

          • Spring Bean初始化后階段

          Spring Bean初始化代碼如下所示:

          protected?Object?initializeBean(final?String?beanName,?final?Object?bean,?@Nullable?RootBeanDefinition?mbd)?{???//Spring?Bean?Aware接口回調(diào)
          ???if?(System.getSecurityManager()?!=?null)?{
          ??????AccessController.doPrivileged((PrivilegedAction)?()?->?{
          ?????????invokeAwareMethods(beanName,?bean);
          ?????????return?null;
          ??????},?getAccessControlContext());
          ???}
          ???else?{
          ??????invokeAwareMethods(beanName,?bean);
          ???}

          ???Object?wrappedBean?=?bean;???//Spring?Bean初始化前階段
          ???if?(mbd?==?null?||?!mbd.isSynthetic())?{
          ??????wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(wrappedBean,?beanName);
          ???}
          ???//Spring?Bean初始化階段
          ???try?{
          ??????invokeInitMethods(beanName,?wrappedBean,?mbd);
          ???}
          ???catch?(Throwable?ex)?{
          ??????throw?new?BeanCreationException(
          ????????????(mbd?!=?null???mbd.getResourceDescription()?:?null),
          ????????????beanName,?"Invocation?of?init?method?failed",?ex);
          ???}???//Spring?Bean初始化后階段
          ???if?(mbd?==?null?||?!mbd.isSynthetic())?{
          ??????wrappedBean?=?applyBeanPostProcessorsAfterInitialization(wrappedBean,?beanName);
          ???}

          ???return?wrappedBean;
          }

          Spring Bean Aware接口回調(diào)階段

          invokeAwareMethods具體代碼如下所示:

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

          Spring Bean初始化前階段

          applyBeanPostProcessorsBeforeInitialization具體代碼如下所示:

          這個方法會調(diào)用BeanPostProcessor#postProcessBeforeInitialization方法。

          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;
          ????}

          Spring Bean初始化階段

          invokeInitMethods具體代碼如下所示:

          protected?void?invokeInitMethods(String?beanName,?final?Object?bean,?@Nullable?RootBeanDefinition?mbd)
          ????????????throws?Throwable?{
          ?????//處理InitializingBean#afterPropertiesSet方法初始化Bean
          ????????boolean?isInitializingBean?=?(bean?instanceof?InitializingBean);
          ????????if?(isInitializingBean?&&?(mbd?==?null?||?!mbd.isExternallyManagedInitMethod("afterPropertiesSet")))?{
          ????????????if?(logger.isTraceEnabled())?{
          ????????????????logger.trace("Invoking?afterPropertiesSet()?on?bean?with?name?'"?+?beanName?+?"'");
          ????????????}
          ????????????if?(System.getSecurityManager()?!=?null)?{
          ????????????????try?{
          ????????????????????AccessController.doPrivileged((PrivilegedExceptionAction)?()?->?{
          ????????????????????????((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.isExternallyManagedInitMethod(initMethodName))?{
          ????????????????invokeCustomInitMethod(beanName,?bean,?mbd);
          ????????????}
          ????????}
          ????}

          Spring Bean初始化后階段

          applyBeanPostProcessorsAfterInitialization具體代碼如下所示:

          這個方法回調(diào)用BeanPostProcessor#postProcessAfterInitialization方法。

          public?Object?applyBeanPostProcessorsAfterInitialization(Object?existingBean,?String?beanName)
          ????????????throws?BeansException?{

          ????????Object?result?=?existingBean;
          ????????for?(BeanPostProcessor?processor?:?getBeanPostProcessors())?{
          ????????????Object?current?=?processor.postProcessAfterInitialization(result,?beanName);
          ????????????if?(current?==?null)?{
          ????????????????return?result;
          ????????????}
          ????????????result?=?current;
          ????????}
          ????????return?result;
          ????}

          Spring Bean銷毀階段

          Spring Bean銷毀階段可以細(xì)分為以下幾個階段:

          • Spring Bean銷毀前階段

          • Spring Bean銷毀階段

          Spring Bean在初始化后會調(diào)用registerDisposableBeanIfNecessary方法注冊到disposableBeans,方便后續(xù)銷毀。

          protected?void?registerDisposableBeanIfNecessary(String?beanName,?Object?bean,?RootBeanDefinition?mbd)?{
          ????????AccessControlContext?acc?=?(System.getSecurityManager()?!=?null???getAccessControlContext()?:?null);
          ????????if?(!mbd.isPrototype()?&&?requiresDestruction(bean,?mbd))?{
          ????????????if?(mbd.isSingleton())?{
          ????????????????//注冊DisposableBeanAdapter,后續(xù)銷毀時用
          ????????????????registerDisposableBean(beanName,
          ????????????????????????new?DisposableBeanAdapter(bean,?beanName,?mbd,?getBeanPostProcessors(),?acc));
          ????????????}
          ????????????else?{
          ????????????????//如果不是單例而且不是原生,比如servlet里context、request等作用域,在一定階段觸發(fā)scope銷毀操作會銷毀Bean
          ????????????????Scope?scope?=?this.scopes.get(mbd.getScope());
          ????????????????if?(scope?==?null)?{
          ????????????????????throw?new?IllegalStateException("No?Scope?registered?for?scope?name?'"?+?mbd.getScope()?+?"'");
          ????????????????}
          ????????????????scope.registerDestructionCallback(beanName,
          ????????????????????????new?DisposableBeanAdapter(bean,?beanName,?mbd,?getBeanPostProcessors(),?acc));
          ????????????}
          ????????}
          ????}
          public?void?destroy()?{?????//Spring銷毀前階段,調(diào)動DestructionAwareBeanPostProcessor#postProcessBeforeDestruction方法
          ????????if?(!CollectionUtils.isEmpty(this.beanPostProcessors))?{
          ????????????for?(DestructionAwareBeanPostProcessor?processor?:?this.beanPostProcessors)?{
          ????????????????processor.postProcessBeforeDestruction(this.bean,?this.beanName);
          ????????????}
          ????????}
          ?????//調(diào)用DisposableBean#destroy方法
          ????????if?(this.invokeDisposableBean)?{
          ????????????if?(logger.isTraceEnabled())?{
          ????????????????logger.trace("Invoking?destroy()?on?bean?with?name?'"?+?this.beanName?+?"'");
          ????????????}
          ????????????try?{
          ????????????????if?(System.getSecurityManager()?!=?null)?{
          ????????????????????AccessController.doPrivileged((PrivilegedExceptionAction)?()?->?{
          ????????????????????????((DisposableBean)?this.bean).destroy();
          ????????????????????????return?null;
          ????????????????????},?this.acc);
          ????????????????}
          ????????????????else?{
          ????????????????????((DisposableBean)?this.bean).destroy();
          ????????????????}
          ????????????}
          ????????????catch?(Throwable?ex)?{
          ????????????????String?msg?=?"Invocation?of?destroy?method?failed?on?bean?with?name?'"?+?this.beanName?+?"'";
          ????????????????if?(logger.isDebugEnabled())?{
          ????????????????????logger.warn(msg,?ex);
          ????????????????}
          ????????????????else?{
          ????????????????????logger.warn(msg?+?":?"?+?ex);
          ????????????????}
          ????????????}
          ????????}
          ?????//調(diào)用自定義銷毀函數(shù)
          ????????if?(this.destroyMethod?!=?null)?{
          ????????????invokeCustomDestroyMethod(this.destroyMethod);
          ????????}
          ????????else?if?(this.destroyMethodName?!=?null)?{
          ????????????Method?methodToInvoke?=?determineDestroyMethod(this.destroyMethodName);
          ????????????if?(methodToInvoke?!=?null)?{
          ????????????????invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
          ????????????}
          ????????}
          ????}

          Spring Bean垃圾收集階段

          Spring Bean在Spring應(yīng)用上下文關(guān)閉后觸發(fā)GC會觸發(fā)Spring Bean垃圾收集。





          粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

          ??????

          ??長按上方微信二維碼?2 秒


          感謝點贊支持下哈?

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    天天插狠狠操 | 97性爱视频 | 91探花秘 在线播放 | 天天干天天射天天 | 欧美日本中文在线 |