9.3.3、Bean的生命周期

1、Bean的作用域


在配置文件中用属性scope标注

(1)标注scope为singleton或者缺省scope属性的Bean在ApplicationContext(IOC容器为BeanFactory非ApplicationContext实现类则不会)启动时就会自动实例化,并且从容器启动到销毁只存在一个实例,容器负责这个实例的全部生命周期的管理。

(2)标注scope为prototype的Bean只在IOC容器的getBean()方法被调用时才会进行实例化,并且每次调用该方法返回的都是不同的实例。

(3)标注socpe为request的Bean对于每一次request都将产生不同Bean实例,并且在一次request结束后Bean的实例将销毁。

(4)标注scope为session的Bean对于每次session会话都只产生一个Bean实例,并且在session失效后自动销毁。

(5)当一个bean的作用域为Global Session,表示在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

需要注意的是,后面三种作用域只针对web应用


2、Bean的生命周期

Bean实例生命周期的执行过程如下:

Spring对bean进行实例化,默认bean是单例;

Spring对bean进行依赖注入;

如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;

如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来;

如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;

如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用;

如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;

如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;

此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;

若bean实现了DisposableBean接口,spring将调用它的destroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;

不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用(在scope为prototype的Bean中配置destroy-method属性无效)。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源(如数据库连接资源),都是客户端代码的职责(让Spring容器释放被prototype作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用)。

例子:

定义两个类Source、JuiceMaker,都实现BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口。

定义类MyPostProcessorImpl实现BeanPostProcessor接口、MyDisposableImpl实现DisposableBean接口

代码如下:

Source:

public class Source implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean{

private String fruit;

private String sugar;

private String size;

/**getter and setter*/

.....

public void setBeanName(String name) {

System.out.println("【Source】调用BeanNameAware接口的setBeanName方法");

}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

System.out.println("【Source】调用BeanFactory接口的setBeanFactory方法");

}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

System.out.println("【Source】调用ApplicationContext接口的setApplicationContext方法");

}

public void afterPropertiesSet() throws Exception {

System.out.println("【Source】调用InitializingBean接口的afterPropertiesSet方法");

}

//自定义初始化和销毁方法

public void init() {

System.out.println("【Source】调用自定义初始化方法初始化");

}

public void destroy() {

System.out.println("【Source】调用自定义销毁方法");

}

}

JuiceMaker的代码和Source类似就不贴出来了,下面来看MyPostProcessorImpl和MyDisposableImpl的代码:

MyPostProcessorImpl:

public class MyPostProcessorImpl implements BeanPostProcessor{

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的对象" + beanName + "开始初始化");

return bean;

}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的对象" + beanName + "初始化完成");

return bean;

}

}

MyDisposableImpl:

public class MyDisposableImpl implements DisposableBean{

public void destroy() throws Exception {

  System.out.println("【MyDisposableImpl】调用DisposableBean接口destroy方法");

}

}

在配置文件中配置bean:

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

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

<bean id="source" class="spring.chapter9.ioc.Source" init-method="init" destroy-method="destroy">

<property name="fruit" value="橙子" ></property>

<property name="sugar" value="三勺" />

<property name="size"  value="大杯" />

</bean>

<bean id="juiceMaker" class="spring.chapter9.ioc.JuiceMaker" init-method="init" destroy-method="destroy">

    <property name="shopName" value="布拉格" />

    <property name="source"  ref="source" />

</bean>

<bean id="beanPostProcessor" class="spring.chapter9.lifecycle.MyPostProcessorImpl" />

<bean id="beanDisposable" class="spring.chapter9.lifecycle.MyDisposableImpl" />

</beans>

注意加粗的部分,分别给bean指定自定义的初始化和销毁方法.

测试:

public class Test {

private static ApplicationContext ctx;

public static void main(String[] args) {

ctx =

new ClassPathXmlApplicationContext("classpath:spring-cfg-ioc.xml");

JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");

juiceMaker.make();

}


由此可见BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口都是针对单个Bean而言的,而BeanPostProcessor接口则是针对每一个Bean(当然不包括实现了这个接口的Bean本身)。DisposableBean是针对Spring IoC容器的。

另外需要注意的是,afterPropertiesSet方法执行完后,如果没有自定义初始化方法,那么Bean的初始化和依赖注入已经完成了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容