請別再問Spring Bean的生命周期了
點擊關注公眾號,Java干貨及時送達

日月更替,周而復始,大自然中的任何生命都有著它的周期,比如螞蟻的壽命只有幾年,而烏龜的壽命卻有幾十年甚至上百年。?
同理,在Spring框架中,Bean對象也有著它的生命周期,然而對于Bean對象的生命周期,我們并不是很清楚,因為Spring幫助我們管理了Bean對象,所以,掌握Bean的生命周期,并知曉Spring在每個階段為我們做了哪些事情是非常有必要的。
Bean的生命周期
對于一個Bean的生命周期,其實非常簡單,無非就是從創(chuàng)建對象到銷毀的過程,但是Spring作為一個可擴展的框架,其在Bean的創(chuàng)建和銷毀過程中加入了非常多的擴展點,這也是為什么Spring能夠蓬勃發(fā)展至今的一個原因。Bean的生命周期大體可以總結為以下幾個階段:
Bean的定義 Bean的注冊 Bean的創(chuàng)建 Bean的注入 Bean的初始化 Bean的銷毀
Bean的定義、注冊及創(chuàng)建過程
其中Bean的定義非常簡單,它是由我們來完成的,例如在Spring的配置文件中配置一個Bean:
<bean?id="user"?class="com.wwj.entity.User">
????<property?name="name"?value="zs"/>
????<property?name="age"?value="22"/>
bean>
又或者是一個注解:
@Component
public?class?User{
?private?String?name;
????private?Integer?age;
}
此時一個Bean就定義好了,接下來Spring在啟動的時候就會將這些定義好的Bean注冊起來,對于配置文件啟動,Spring會解析配置文件中的配置進行Bean的注冊,具體體現在refresh方法:
@Override
public?void?refresh()?throws?BeansException,?IllegalStateException?{
????synchronized?(this.startupShutdownMonitor)?{
????????//?Prepare?this?context?for?refreshing.
????????prepareRefresh();
????????//?Tell?the?subclass?to?refresh?the?internal?bean?factory.
????????ConfigurableListableBeanFactory?beanFactory?=?obtainFreshBeanFactory();
????????//?Prepare?the?bean?factory?for?use?in?this?context.
????????prepareBeanFactory(beanFactory);
????????//?Allows?post-processing?of?the?bean?factory?in?context?subclasses.
????????postProcessBeanFactory(beanFactory);
????????//?Invoke?factory?processors?registered?as?beans?in?the?context.
????????invokeBeanFactoryPostProcessors(beanFactory);
????????//?Register?bean?processors?that?intercept?bean?creation.
????????registerBeanPostProcessors(beanFactory);
????????//?Initialize?message?source?for?this?context.
????????initMessageSource();
????????//?Initialize?event?multicaster?for?this?context.
????????initApplicationEventMulticaster();
????????//?Initialize?other?special?beans?in?specific?context?subclasses.
????????onRefresh();
????????//?Check?for?listener?beans?and?register?them.
????????registerListeners();
????????//?Instantiate?all?remaining?(non-lazy-init)?singletons.?實例化Bean
????????finishBeanFactoryInitialization(beanFactory);
????????//?Last?step:?publish?corresponding?event.
????????finishRefresh();
????}
}
其中finishBeanFactoryInitialization(beanFactory)方法就是用來實例化所有的單例Bean,該方法源碼如下:
protected?void?finishBeanFactoryInitialization(ConfigurableListableBeanFactory?beanFactory)?{
????//?Initialize?conversion?service?for?this?context.
????if?(beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)?&&
????????beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME,?ConversionService.class))?{
????????beanFactory.setConversionService(
????????????beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME,?ConversionService.class));
????}
????//?Register?a?default?embedded?value?resolver?if?no?bean?post-processor
????//?(such?as?a?PropertyPlaceholderConfigurer?bean)?registered?any?before:
????//?at?this?point,?primarily?for?resolution?in?annotation?attribute?values.
????if?(!beanFactory.hasEmbeddedValueResolver())?{
????????beanFactory.addEmbeddedValueResolver(strVal?->?getEnvironment().resolvePlaceholders(strVal));
????}
????//?Initialize?LoadTimeWeaverAware?beans?early?to?allow?for?registering?their?transformers?early.
????String[]?weaverAwareNames?=?beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,?false,?false);
????for?(String?weaverAwareName?:?weaverAwareNames)?{
????????getBean(weaverAwareName);
????}
????//?Stop?using?the?temporary?ClassLoader?for?type?matching.
????beanFactory.setTempClassLoader(null);
????//?Allow?for?caching?all?bean?definition?metadata,?not?expecting?further?changes.
????beanFactory.freezeConfiguration();
????//?Instantiate?all?remaining?(non-lazy-init)?singletons.
????beanFactory.preInstantiateSingletons();
}
我們不具體分析所有的方法,只看重要的部分,其中beanFactory.preInstantiateSingletons()方法實例化了所有的單例Bean,既然知道了創(chuàng)建Bean的地方,那么Spring是如何知道需要創(chuàng)建哪些Bean的呢?換句話說,配置文件是在哪里進行解析的呢?我們回到最初的refresh方法,其中有一個ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),它就是來解析配置文件的,源碼如下:
protected?ConfigurableListableBeanFactory?obtainFreshBeanFactory()?{
????refreshBeanFactory();
????ConfigurableListableBeanFactory?beanFactory?=?getBeanFactory();
????if?(logger.isDebugEnabled())?{
????????logger.debug("Bean?factory?for?"?+?getDisplayName()?+?":?"?+?beanFactory);
????}
????return?beanFactory;
}
它調用了refreshBeanFactory()方法:
@Override
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);
????}
}
該方法又調用了loadBeanDefinitions(beanFactory)方法:
@Override
protected?void?loadBeanDefinitions(DefaultListableBeanFactory?beanFactory)?throws?BeansException,?IOException?{
????//?Create?a?new?XmlBeanDefinitionReader?for?the?given?BeanFactory.
????XmlBeanDefinitionReader?beanDefinitionReader?=?new?XmlBeanDefinitionReader(beanFactory);
????//?Configure?the?bean?definition?reader?with?this?context's
????//?resource?loading?environment.
????beanDefinitionReader.setEnvironment(this.getEnvironment());
????beanDefinitionReader.setResourceLoader(this);
????beanDefinitionReader.setEntityResolver(new?ResourceEntityResolver(this));
????//?Allow?a?subclass?to?provide?custom?initialization?of?the?reader,
????//?then?proceed?with?actually?loading?the?bean?definitions.
????initBeanDefinitionReader(beanDefinitionReader);
????loadBeanDefinitions(beanDefinitionReader);
}
接著調用loadBeanDefinitions(beanDefinitionReader)方法:
protected?void?loadBeanDefinitions(XmlBeanDefinitionReader?reader)?throws?BeansException,?IOException?{
????Resource[]?configResources?=?getConfigResources();
????if?(configResources?!=?null)?{
????????reader.loadBeanDefinitions(configResources);
????}
????String[]?configLocations?=?getConfigLocations();
????if?(configLocations?!=?null)?{
????????reader.loadBeanDefinitions(configLocations);
????}
}
到這里就差不多了,調用棧比較深,就不繼續(xù)往下看了,這里就是在解析xml文件并創(chuàng)建Bean實例。
Bean的注入過程
在創(chuàng)建對象過程中,我們還需要對對象的屬性進行賦值,那么Spring是如何實現的呢?
protected?Object?doCreateBean(String?beanName,?RootBeanDefinition?mbd,?@Nullable?Object[]?args)?throws?BeanCreationException?{
????BeanWrapper?instanceWrapper?=?null;
????if?(mbd.isSingleton())?{
????????instanceWrapper?=?(BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
????}
????if?(instanceWrapper?==?null)?{
????????instanceWrapper?=?this.createBeanInstance(beanName,?mbd,?args);
????}
????......
????????try?{
????????????//?看這里
????????????this.populateBean(beanName,?mbd,?instanceWrapper);
????????????exposedObject?=?this.initializeBean(beanName,?exposedObject,?mbd);
????????}?catch?(Throwable?var18)?{
????????}
}
this.populateBean(beanName, mbd, instanceWrapper)方法就是用來實現屬性賦值的:
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.
????if?(!mbd.isSynthetic()?&&?hasInstantiationAwareBeanPostProcessors())?{
????????for?(BeanPostProcessor?bp?:?getBeanPostProcessors())?{
????????????if?(bp?instanceof?InstantiationAwareBeanPostProcessor)?{
????????????????InstantiationAwareBeanPostProcessor?ibp?=?(InstantiationAwareBeanPostProcessor)?bp;
????????????????if?(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),?beanName))?{
????????????????????return;
????????????????}
????????????}
????????}
????}
????PropertyValues?pvs?=?(mbd.hasPropertyValues()???mbd.getPropertyValues()?:?null);
????int?resolvedAutowireMode?=?mbd.getResolvedAutowireMode();
????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)?{
????????????autowireByName(beanName,?mbd,?bw,?newPvs);
????????}
????????//?Add?property?values?based?on?autowire?by?type?if?applicable.
????????if?(resolvedAutowireMode?==?AUTOWIRE_BY_TYPE)?{
????????????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?(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;
????????????}
????????}
????}
????if?(needsDepCheck)?{
????????if?(filteredPds?==?null)?{
????????????filteredPds?=?filterPropertyDescriptorsForDependencyCheck(bw,?mbd.allowCaching);
????????}
????????checkDependencies(beanName,?mbd,?filteredPds,?pvs);
????}
????if?(pvs?!=?null)?{
????????applyPropertyValues(beanName,?mbd,?bw,?pvs);
????}
}
這個方法非常地長,就不帶大家一句一句看了,感興趣的同學可以自己翻閱一下源碼。
Bean的銷毀過程
銷毀過程就非常簡單了,當調用容器的close方法時,Spring就會自動去調用Bean的銷毀方法實現銷毀邏輯。
Bean的生命周期(詳細)
以上內容只是對Bean生命周期的一個大概介紹,實際上, Spring提供了非常多的擴展點穿插在整個生命周期中,具體流程如下:
創(chuàng)建Bean實例 調用Bean中的setter()方法設置屬性值 檢查Bean是否實現了Aware接口,若實現了,則調用對應的接口方法 若容器中有BeanPostProcessor,則調用其postProcessAfterInitialization 檢查Bean是否實現了InitializingBean,若實現了,則調用其afterPropertiesSet方法 檢查是否指定了Bean的init-method屬性,若指定了,則調用其指定的方法 若容器中有BeanPostProcessor,則調用其postProcessorAfterInitialization 檢查Bean是否實現了DisposableBean,若實現了,則調用其方法 檢查是否指定了Bean的destroy-method屬性,若指定了,則調用其指定的方法
我們可以來測試一下:
public?class?User?implements?ApplicationContextAware,?InitializingBean,?DisposableBean?{
????private?String?name;
????private?Integer?age;
????public?User()?{
????????System.out.println("1--》創(chuàng)建User實例");
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????????System.out.println("2--》設置User的name屬性");
????}
????public?void?setAge(Integer?age)?{
????????this.age?=?age;
????????System.out.println("2--》設置User的age屬性");
????}
????public?void?init()?{
????????System.out.println("6--》調用init-method屬性指定的方法");
????}
????public?void?myDestroy()?{
????????System.out.println("9--》調用destroy-method屬性指定的方法");
????}
????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????System.out.println("3--》調用對應Aware接口的方法");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("5--》調用InitializingBean接口的afterPropertiesSet方法");
????}
????@Override
????public?void?destroy()?throws?Exception?{
????????System.out.println("8--》調用DisposableBean接口的destroy方法");
????}
}
這個Bean實現了Spring提供的一些擴展點,包括ApplicationContextAware、InitialzingBean、DisposableBean等,所以我們來編寫一個Bean的后置處理器:
public?class?MyBeanPostProcessor?implements?BeanPostProcessor?{
????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????System.out.println("7--》調用MyBeanPostProcessor的postProcessBeforeInitialization方法");
????????return?BeanPostProcessor.super.postProcessAfterInitialization(bean,?beanName);
????}
????@Override
????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????System.out.println("4--》調用MyBeanPostProcessor的postProcessAfterInitialization方法");
????????return?BeanPostProcessor.super.postProcessBeforeInitialization(bean,?beanName);
????}
}
最后將它們注冊到容器中,并且指定Bean對應的初始化和銷毀方法:
@Configuration
public?class?MyBeanConfig?{
????@Bean(initMethod?=?"init",?destroyMethod?=?"myDestroy")
????public?User?user()?{
????????User?user?=?new?User();
????????user.setName("zs");
????????user.setAge(30);
????????return?user;
????}
????@Bean
????public?BeanPostProcessor?beanPostProcessor()?{
????????return?new?MyBeanPostProcessor();
????}
}
運行結果如下:
1--》創(chuàng)建User實例
2--》設置User的name屬性
2--》設置User的age屬性
3--》調用對應Aware接口的方法
4--》調用MyBeanPostProcessor的postProcessAfterInitialization方法
5--》調用InitializingBean接口的afterPropertiesSet方法
6--》調用init-method屬性指定的方法
7--》調用MyBeanPostProcessor的postProcessBeforeInitialization方法
8--》調用DisposableBean接口的destroy方法
9--》調用destroy-method屬性指定的方法
正如我們預想的那樣,Spring依次調用了每個擴展點,熟悉了整個Bean的生命周期和擴展點之后,我們就能夠在每個階段做我們想做的事情,實現業(yè)務的定制化。
往 期 推 薦
點分享
點收藏
點點贊
點在看





