Spring Bean生命周期
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
? 作者?|? Gouden
來源 |? urlify.cn/2QZr6f
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((PrivilegedActionSpring 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((PrivilegedExceptionActionSpring 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((PrivilegedExceptionActionSpring Bean垃圾收集階段
Spring Bean在Spring應(yīng)用上下文關(guān)閉后觸發(fā)GC會觸發(fā)Spring Bean垃圾收集。
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼?2 秒
感謝點贊支持下哈?
