`
Luob.
  • 浏览: 1572109 次
  • 来自: 上海
社区版块
存档分类
最新评论

Spring Bean的管理

阅读更多
目录
1.spring 实例化 bean 的几种方式
2.spring 中bean 的作用域
3.spring 管理的bean 在什么时候初始化 和 销毁
4.spring bean 的 init-method  destroy-method

1.下面 我们来看看spring的 实例化bean的 几种方式
1.使用类构造器实例化bean
   <!--1.使用类构造器实例化bean--->
  <bean id="personService" class="com.person.service.impl.PersonServiceBean">
  </bean>


2 使用 静态工厂方法来实例化
<!-- 2.使用 静态工厂方法来实例化 bean -->
	<bean id="personService2" class="com.person.service.impl.PerssonServiceFactory" factory-method="createPersonService"/>
	

package com.person.service.impl;

import com.person.service.PersonService;

public class PerssonServiceFactory {
	//使用这个工厂中的静态方法
	public static PersonService createPersonService(){
		return new PersonServiceBean();
	}
}


3. 使用 实例工厂方式来实例化bean
<!-- 使用 实例工厂方式来实例化bean -->
	<bean id="perssonServiceFactory" class="com.person.service.impl.PerssonServiceFactory"/>
	<bean id="personService3" factory-bean="perssonServiceFactory" factory-method="createPersonService2"/>


package com.person.service.impl;

import com.person.service.PersonService;

public class PerssonServiceFactory {
	
	//使用 静态工厂方法来实例化 bean
	public static PersonService createPersonService(){
		return new PersonServiceBean();
	}
	
	//使用 实例工厂方式来实例化bean
	public PersonService createPersonService2(){
		return new PersonServiceBean();
	}
}

//测试
	@Test
	public void init3(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		
		
		//方法一  获取服务层对象
		PersonService personService=(PersonService)ctx.getBean("personService2");
		//方法二
		PersonService personService1=ctx.getBean("personService3",PersonService.class);
		
		personService.save();
		personService1.save();
	}


2.弄了这么多 那么spring 中每次 getBean();这个方法返回的对象  是同一个吗??
@Test //测试 spring 容器中的 bean 的作用域
	public void init4(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		//方法一  获取服务层对象
		PersonService personService=(PersonService)ctx.getBean("personService");
		PersonService personService1=(PersonService)ctx.getBean("personService");
		//方法二
		PersonService personService2=ctx.getBean("personService",PersonService.class);
		
		System.out.println(personService==personService1); //true
		System.out.println(personService1==personService2); //true 
		 
	}

//以上 说明 是同一个对象 ,说明了spring 默认 的bean 是 单例模式 Singleton

spring bean 的作用域 scope

Singleton
在每个Spring IOC容器中一个bean的定义只有一个对象实例,默认情况下,会在容器服务器启动时初始化bean,但我们可以制定Bean 节点 lazy-init="true" 来延迟初始化bean,这个时候,只有第一个获取bean才会初始化bean.如:
<bean id="XXX" class="com.person.serivce.impl.PersonServiceBean" lazy-init="true"/>
如果 相对 spring文件中的所有bean 都 延迟初始化,可以在根节点beans 设置  default-lazy-init="true" 如下:
<beans  default-init="true"/>


prototype:每次从容器获取的bean 都是一个新的对象. (原型)

//对于 web 应用来说
request
session
global session

//修改spring 配置 来测试
<!-- 使用 静态工厂方法来实例化 bean 加入 scope 范围-->  
	<bean id="personService2" class="com.person.service.impl.PerssonServiceFactory" factory-method="createPersonService" scope="prototype"/>

@Test //测试 spring 容器中的 bean 的作用域
	public void init5(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		//方法一  获取服务层对象
		PersonService personService=(PersonService)ctx.getBean("personService2");
		PersonService personService1=(PersonService)ctx.getBean("personService2");
		//方法二
		PersonService personService2=ctx.getBean("personService2",PersonService.class);
		
		System.out.println(personService==personService1); //false
		System.out.println(personService1==personService2); //false 
	}


//说明 设置 scope="prototype" 后变成了 原型  每次 获取都是不同的对象

3.看看 spring 在什么时候 初始化bean  (在 配置 的bean对应的类中 加个 构造方法 就可以测试了)

1 先测试  singleton 范围
package com.person.service.impl;

import com.person.service.PersonService;

public class PersonServiceBean implements PersonService {
	
	//测试 spring 在什么时候初始化 bean
	public PersonServiceBean() {
		System.out.println("我被实例化了!");
	}
	
	public void save(){
		System.out.println("我就是save方法!");
	}
}

@Test //测试 spring的 初始化
	public void init(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		
	}

// 发现 打印 出了 "我被实例化了!"  说明 spring 默认情况下 是加载 spring配置文件的时候就初始化了 bean

2.在来测试 scope="prototype"

	@Test //测试 spring的 初始化
	public void init(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		
		System.out.println("开始调用 getBean方法");
		//方法一  获取服务层对象
		PersonService personService=(PersonService)ctx.getBean("personService");
		//方法二
		PersonService personService1=ctx.getBean("personService",PersonService.class);
		
		
		//personService.save();
		//personService1.save();
	}


// 发现 打印出 "开始调用 getBean方法" 之后 才打印出 "我被实例化了!"  "我被实例化了!"
// 说明 scope="prototype" 是在 getBean方法后  才被实例化

3.再来看延迟初始化 lazy-init="true";
	<!-- 使用 延迟初始化  -->
	<bean id="personService" class="com.person.service.impl.PersonServiceBean" lazy-init="true">
	</bean>



	@Test //测试 spring的 初始化
	public void init(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		
		System.out.println("开始调用 getBean方法");
		//方法一  获取服务层对象
		PersonService personService=(PersonService)ctx.getBean("personService");
		//方法二
		PersonService personService1=ctx.getBean("personService",PersonService.class);
		
		
		//personService.save();
		//personService1.save();
	}

// 发现 打印出 "开始调用 getBean方法" 之后 才打印出 "我被实例化了!" 

说明 lazy-init="true" 也是在 getBean方法后才被初始化   但是 使用的是同一个对象 所以 只打印出了一句 "我被实例化了!"  .而scope="prototype" 是原型 所以 打印出了 两句  "我被实例化了!" .

4.如果 我们想在 spring 初始化bean实例后  执行一个方法 , 或者 在  bean销毁后 执行一个方法 (比如 资源的打开  和 使用完后 资源的关闭:写到这 大家是不是 就想到了 打开数据库连接 和 关闭呀)

package com.person.service.impl;

import com.person.service.PersonService;

public class PersonServiceBean implements PersonService {
	
	//初始化后 执行的方法
	public void init(){
		System.out.println("打开数据库的连接");
	}
	
	//销毁后执行的方法
	public void destroy(){
		System.out.println("关闭 数据的连接资源");
	}
	
	//测试 spring 在什么时候初始化 bean
	public PersonServiceBean() {
		System.out.println("我被实例化了!");
	}
	
	public void save(){
		System.out.println("我就是save方法!");
	}
}


使用 这两个属性  init-method  , destroy-method
<!-- 使用个 实例工厂方式来实例化bean -->
	<bean id="perssonServiceFactory" class="com.person.service.impl.PerssonServiceFactory"/>
	<bean id="personService3" factory-bean="perssonServiceFactory" factory-method="createPersonService2" init-method="init" destroy-method="destroy"/>


@Test  //测试 spring 的 init-method  , destroy-method
	public void init6(){
		//注意这里  ApplicationContext 接口 没有 close 方法 只有 用  父接口 
		AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		//方法二
		PersonService personService1=ctx.getBean("personService3",PersonService.class);
		personService1.save();
		ctx.close(); 
	}

// 发现  init 和 destroy 方法 都执行了
1
1
分享到:
评论
1 楼 liuzl121 2012-12-14  
顶下,谢楼主的总结,对于我这样的初学者很有用,希望楼主继续总结。

相关推荐

Global site tag (gtag.js) - Google Analytics