spring生命周期管理

1. 前言

本文主要記錄一下Spring中bean的生命周期绑警,即從bean實(shí)例化到最終銷毀的過(guò)程中一些重要的節(jié)點(diǎn)姊氓,以及Spring提供的在bean這些節(jié)點(diǎn)過(guò)程中的一些操作在讶。

2. Bean生命周期

如下圖所示:

Spring生命周期.png

2.1 BeanFactoryPostProcessor

該接口有如下方法:

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

該接口的實(shí)現(xiàn)類最先被實(shí)例化名挥,它是一個(gè)spring容器級(jí)別的后置處理器瓮顽,盡管此時(shí)所有的bean都沒(méi)有被實(shí)例化出來(lái),但是bean的配置文件已經(jīng)被分析完围橡,所有的bean的定義信息(spring中使用類BeanDefinition表示)已經(jīng)加載暖混,可以通過(guò)ConfigurableListableBeanFactory # getBeanDefinition(String beanName)獲取,獲取到BeanDefiniton意味著你可以修改bean的屬性了翁授。

BeanFactoryPostProcessor 的一些實(shí)現(xiàn)類

  1. PropertyPlaceholderConfigurer
    這個(gè)很多人用過(guò)拣播,從key=value形式的配置文件中加載配置信息晾咪,并通過(guò)${propertyName}的形式設(shè)置到bean屬性上,如下面這種形式:
<context:property-placeholder
         location="classpath:db.properties"
          file-encoding="utf8"
/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.user}"/>
        <property name="password" value="${db.password}"/>
</bean>

注:上面使用了簡(jiǎn)易的形式<context:property-placeholder .../>, 這種情況下會(huì)創(chuàng)建PropertyPlaceholderConfigurer對(duì)應(yīng)的bean贮配。關(guān)于<context>命名空間谍倦,請(qǐng)看 附錄1

  1. PropertyOverrideConfigurer
    這個(gè)和 PropertyPlaceholderConfigurer一樣將bean的屬性卸載properties文件中,用法如下:
首先假設(shè)在db.properties中如下內(nèi)容:
dataSource.username=root
dataSource.password=root
同樣是name=value的形式泪勒,但是name必須是<beanName>.<beanPropertyName>格式

然后在applicationContext.xml中如下定義bean即可:
 <!--這個(gè)命名空間會(huì)加載PropertyOverrideConfigurer-->
<context:property-override location="db.properties"/>

<!--bean id需要和db.properties中beanName一樣-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
</bean>
PropertyOverrideConfigurer這個(gè)后置處理器會(huì)根據(jù)db.properties中dataSource這個(gè)bean的名字找到屬性昼蛀,然后填充到dataSource這個(gè)bean中

2.2.2 BeanPostProcessor

BeanPostProcessor有兩個(gè)接口方法:

Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

BeanPostProcessor在普通bean實(shí)例化之前就就創(chuàng)建了,但是他的兩個(gè)接口方法在卻在普通bean實(shí)例化(即創(chuàng)建bean類的對(duì)象)圆存,通過(guò)setter完成了屬性注入之后調(diào)用叼旋,這兩個(gè)方法在bean初始化前后調(diào)用(bean初始化是指調(diào)用xml中bean定義中init-method指定的方法,或者bean實(shí)現(xiàn)了InitializingBean接口沦辙,調(diào)用接口方法)夫植,詳細(xì)的可見(jiàn)上圖。

BeanPostProcessor的一些實(shí)現(xiàn)類

  1. AutowiredAnnotationBeanPostProcessor
    用于使用@Autowired@Value注解的解析
  2. RequiredAnnotationBeanPostProcessor
    用于使用@Require注解的解析
  3. CommonAnnotationBeanPostProcessor
    用于使用@Resource, @PostConstruct,@PreDestroy注解的解析油讯。

上面三類在在基于注解的方式裝配bean時(shí)經(jīng)常使用详民,當(dāng)在xml文件里配置<context:annotation-config />時(shí),spring會(huì)創(chuàng)建上面三類PostProcessor陌兑,同樣輸入context空間沈跨,參考 附錄1

  1. ScheduledAnnotationBeanPostProcessor
    用于使用了@Scheduled注解的方法的解析,在xml中添加<task:annotation-driven>時(shí)會(huì)創(chuàng)建這個(gè)PostProcessor, 如下例所示:
 <beans>
   <task:annotation-driven scheduler="taskScheduler"/>
   
   <task:scheduler id="taskScheduler" pool-size="42"/>
   
   <task:scheduled-tasks scheduler="taskScheduler">
         <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
   </task:scheduled-tasks>
   
   <bean id="myTask" class="com.foo.MyTask"/>
</beans>
這個(gè)例子來(lái)自于spring代碼@EnableScheduling注釋

2.2.3 ApplicationContextAware

它只有一個(gè)接口方法setApplicationContext(ApplicationContext apc), 實(shí)現(xiàn)它的bean而言诀紊,apc即該bean運(yùn)行時(shí)所處的applicationContext谒出,上圖沒(méi)有畫(huà)出它的調(diào)用時(shí)機(jī),它在BeanFactoryAware # setBeanFactory之后調(diào)用邻奠。

實(shí)現(xiàn)ApplicationContextAware的類

  1. EventListenerMethodProcessor
    spring中事件機(jī)制中笤喳,用來(lái)處理bean中使用了@EventListener標(biāo)注成事件接收這個(gè)的method。
    關(guān)于事件機(jī)制參考spring 事件機(jī)制

附錄1 - context命名空間

spring-context的jar包中META-INF目錄下有文件‘spring.handlers’中有這樣一行http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler, context命名空間加載了類ContextNamespaceHandler碌宴,下面是這個(gè)類的init方法:

@Override
    public void init() {
        registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
        registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
        registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
        registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
    }

包含了context這個(gè)命名空間下所有子元素對(duì)應(yīng)的Parser, 這寫(xiě)parser負(fù)責(zé)解析xml元素杀狡,然后創(chuàng)建對(duì)應(yīng)BeanDefinition

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贰镣,隨后出現(xiàn)的幾起案子呜象,更是在濱河造成了極大的恐慌,老刑警劉巖碑隆,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恭陡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡上煤,警方通過(guò)查閱死者的電腦和手機(jī)休玩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拴疤,你說(shuō)我怎么就攤上這事永部。” “怎么了呐矾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵苔埋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蜒犯,道長(zhǎng)组橄,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任愧薛,我火速辦了婚禮晨炕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毫炉。我一直安慰自己瓮栗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布瞄勾。 她就那樣靜靜地躺著费奸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪进陡。 梳的紋絲不亂的頭發(fā)上愿阐,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音趾疚,去河邊找鬼缨历。 笑死,一個(gè)胖子當(dāng)著我的面吹牛糙麦,可吹牛的內(nèi)容都是我干的辛孵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼赡磅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼魄缚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起焚廊,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冶匹,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后咆瘟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體嚼隘,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年袒餐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了飞蛹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片须肆。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖桩皿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幢炸,我是刑警寧澤泄隔,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站宛徊,受9級(jí)特大地震影響佛嬉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闸天,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一暖呕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苞氮,春花似錦湾揽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至贷帮,卻和暖如春戚揭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撵枢。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工民晒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锄禽。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓潜必,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親沟绪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子刮便,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)绽慈,斷路器恨旱,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評(píng)論 6 342
  • 什么是Spring Spring是一個(gè)開(kāi)源的Java EE開(kāi)發(fā)框架。Spring框架的核心功能可以應(yīng)用在任何Jav...
    jemmm閱讀 16,445評(píng)論 1 133
  • 最近部門(mén)有三位同事要離職,其中一位與我同期入職钝凶,本來(lái)部門(mén)人就不多仪芒,如此規(guī)模的離職讓我感到很受傷唁影。 有人會(huì)說(shuō),同事嘛...
    日月空灝瑜閱讀 784評(píng)論 0 1
  • 《心靈地圖》是龍門(mén)院推出的人物訪談?dòng)涗洠闪糊埵駬?dān)任采訪者饺蔑,選取在教育锌介、文化、科學(xué)猾警、商業(yè)等領(lǐng)域里做出個(gè)人特色作品孔祸,...
    龍門(mén)院的龍公子閱讀 2,240評(píng)論 2 1