`
DXL_xiaoli
  • 浏览: 69362 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

体验spring(三)---Bean的生命周期及作用域

阅读更多

 

Bean 的生命周期及作用域

 

BeanFactory Bean 的生命周期:

1、    容器寻找 Bean 的定义信息并将其实例化。

2、   使用依赖注入, spring 按照 Bean 定义信息配置 Bean 的所有属性。

3、   如果 Bean 实现了 BeanNameAware 接口,工厂调用 Bean setBeanName() 方法传递 Bean id

4、   如果 Bean 实现了 BeanFactoryAware 接口,工厂调用 setBeanFactory() 方法传入工厂自身。

5、   如果有 BeanPostProcessor Bean 关联,那么其 postProcessBeforeInitialization() 方法将调被调用

6、   如果 Bean 指定了 init method 方法,将被调用

7、   如果有 BeanPostProcess Bean 关联,那么其 postProcessAfterInitialization() 方法将被调用。

Bean 在加载容器时创建 Bean 初始化时执行 init-method 方法、 Bean 被关闭时执行 destory-method 方法。

 

消除 BeanFactory bean 的方法:

1、    如果 Bean 实现了 DisposableBean 接口, destory() 方法被调用

2、   如指定了定制的销毁方法,就调用这个方法

注: Bean spring 应用上下文中的生命周期与在 BeanFactory 中的生命周期只有一点不同:即 Bean 实现了 ApplicationContextAware 接口, setApplicationContext() 放法会被调用。

案例:简单介绍Bean的生命周期

public class CycleLifeService implements BeanNameAware, BeanFactoryAware,BeanPostProcessor{
 private String say;//say的属性
 private Test test;//java类的实例

public void setSay(String say) {
	this.say = say;
}

public Test getTest() {
	return test;
}

public void setTest(Test test) {
	this.test = test;
}
public void test(){
	System.out.println("-------------"+this.say);
}
//初始化的方法
public  void init(){
	System.out.println("初始化方法....");
	
}
//销毁的方法
public void  destroy(){
	System.out.println("销毁方法.....");
}
//设置Bean的name
@Override
public void setBeanName(String name) {
	System.out.println("===="+name);
	
}

@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
// 设置一个beanFactory
	System.out.println(BeanFactory.class);
	
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
		throws BeansException {
	System.out.println("------后"+beanName);
	return bean;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
		throws BeansException {
    System.out.println("--------前"+beanName);
	return bean;
}
}
Test的类
public class Test {
	public void test() {
		System.out.println("======================");

	}
}
applicationContext.xml文件
文件中定义的初始化的方法和销毁的方法
<bean id="cycleLifeService" class="cn.csdn.cyclelife.CycleLifeService"
		init-method="init" destroy-method="destroy">
		<property name="say">
			<value>你好!!!</value>
		</property>

		<property name="test">
			<ref bean="test"></ref>
		</property>

	</bean>
<bean id="test" class="cn.csdn.cyclelife.Test"/>
其中的init-method方法在Bean实例化时被调用;destory-method方法在Bean从容器删除之前被调用

 

Bean 的作用域

Spring Framework 支持五种作用域(其中有三种只能用在基于 web Spring ApplicationContext )。

1 singleton :在每个Spring IoC 容器中一个bean 定义对应一个对象实例。( 在初始化容器时,创建一个 bean 的实例对象

2 prototype : 一个bean 定义对应多个对象实例。( 在每次请求该 bean 时,都会创建一个 bean 的实例对象 )

3 request :在一次HTTP 请求中,一个bean 定义对应一个实例;即每次HTTP 请求将会有各自的bean 实例,它们依据某个bean 定义创建而成。该作用域仅在基于webSpring ApplicationContext 情形下有效。

4 session : 在一个HTTP Session 中,一个bean 定义对应一个实例。该作用域仅在基于webSpring ApplicationContext 情形下有效。

5 global session :在一个全局的HTTP Session 中,一个bean 定义对应一个实例。典型情况下,仅在使用portlet context 的时候有效。该作用域仅在基于webSpring ApplicationContext 情形下有效。

我们在 spring 中常用的两种作用域: singleton prototype 一下主要详细介绍该两种作用域。

第一种: 
Singleton作用域:
当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。
<bean id="studentServiceImpl" class="cn.csdn.service.StudentServiceImpl"
		scope="singleton">
		<property name="studentDaoImpl" ref="studentDaoImpl">

		</property>
	</bean>

public class StudentServiceImpl {

	private StudentDaoImpl studentDaoImpl;

	public void setStudentDaoImpl(StudentDaoImpl studentDaoImpl) {
		this.studentDaoImpl = studentDaoImpl;
	}

	@Override
	public void insert() {
		studentDaoImpl.insert();

	}

}

public class StudentDaoImpl {

	@Override
	public void insert() {
		System.out.println("插入成功.....");
		
	}

}
第二种:
Prototype作用域:
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。根据经验,对所有有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

注:Spring不能对一个prototype bean的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。
  <!-- 使用singleton模式创建bean实例对象 -->

    <bean id="cityService" class="cn.csdn.service.CityService" scope="prototype"></bean>

 

 

补充:延迟初始化:  

   依赖:

    延迟初始化 :lazy-init:false true;

    false: 加载容器时 初始化对象

    true :第一次调用时初始化对象

   

    在根标签中有一个 default-lazy-init 的属性 如果该属性设置为 true 该文件中的所有 bean 都会被延迟初始化。

   

    注意:如果在 lazy-init ='false' bean 中,引用 lazy-init ="true" bean, 那么 lazy-init 就失去了延迟的效果。

  

      <

2
2
分享到:
评论
1 楼 Onion_Lou 2011-04-21  
文章写的不错、
提点建议、
你用FCK的代码工具编辑JAVA代码、文章会更整洁一点

相关推荐

Global site tag (gtag.js) - Google Analytics