Spring Bean作用域介紹(轉(zhuǎn)帖)
Posted on 2009-09-14 10:30 cyantide 閱讀(606) 評(píng)論(0) 編輯 收藏 所屬分類: springsingleton:SpringIoc容器只會(huì)創(chuàng)建該Bean的唯一實(shí)例,所有的請(qǐng)求和引用都只使用這個(gè)實(shí)例
Property: 每次請(qǐng)求都創(chuàng)建一個(gè)實(shí)例
request: 在一次Http請(qǐng)求中,容器會(huì)返回該Bean的同一個(gè)實(shí)例,而對(duì)于不同的用戶請(qǐng)求,會(huì)返回不同的實(shí)例。需要注意的是,該作用域僅在基于Web的 Spring ApplicationContext情形下有效,以下的session和global Session也是如此
session:同上,唯一的區(qū)別是請(qǐng)求的作用域變?yōu)榱藄ession
global session:全局的HttpSession中,容器會(huì)返回該bean的同一個(gè)實(shí)例,典型為在是使用portlet context的時(shí)候有效(這個(gè)概念本人也不懂)
注意:如果要用到request,session,global session時(shí)需要配置
servlet2.4及以上:
在web.xml中添加:
<listener>
<listener-class>org.springframework.web.context.scope.RequestContextListener />
</listener>
servlet2.4以下:
需要配置一個(gè)過(guò)濾器
<filter>
<filter-name>XXXX</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
<filter-mapping>
<filter-name>XXXX</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
另外,從2.0開始,可以自己定義作用域,但需要實(shí)現(xiàn)scope,并重寫get和remove方法
特別要引起注意的是:
一般情況下前面兩種作用域是夠用的,但如果有這樣一種情況:singleton類型的bean引用一個(gè)prototype的bean時(shí)會(huì)出現(xiàn)問(wèn)題,因?yàn)? singleton只初始化一次,但prototype每請(qǐng)求一次都會(huì)有一個(gè)新的對(duì)象,但prototype類型的bean是singleton類型 bean的一個(gè)屬性,理所當(dāng)然不可能有新prototpye的bean產(chǎn)生,與我們的要求不符
解決方法:
1.放棄Ioc,這與設(shè)計(jì)初衷不符,并代碼間會(huì)有耦合
2,Lookup方法注入,推薦
但在用Lookup方法注入時(shí)也需要注意一點(diǎn):需要在引用的Bean中定一個(gè)一個(gè)抽象地返回被引用對(duì)象的方法
package com.huyong.lookup;
import java.util.Calendar;
/**
* @author HuYong Email:yate7571@hotmail.com
*/
public class CurrentTime {
private Calendar now = Calendar.getInstance();
public void printCurrentTime() {
System.out.println("Current Time:" + now.getTime());
}
}
package com.huyong.lookup;
/**
* @author HuYong Email:yate7571@hotmail.com
*/
public abstract class LookupBean {
private CurrentTime currentTime;
public CurrentTime getCurrentTime() {
return currentTime;
}
public void setCurrentTime(CurrentTime currentTime) {
this.currentTime = currentTime;
}
public abstract CurrentTime createCurrentTime();
}
<?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-2.0.xsd">
<bean id="currentTime" class="com.huyong.lookup.CurrentTime"
scope="prototype">
</bean>
<bean id="lookupBean" class="com.huyong.lookup.LookupBean"
scope="singleton">
<lookup-method name="createCurrentTime" bean="currentTime" />
<property name="currentTime" ref="currentTime"></property>
</bean>
</beans>
Main Test:
package com.huyong.lookup;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* @author HuYong Email:yate7571@hotmail.com
*/
public class LookupMain {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ClassPathResource resource = new ClassPathResource(
"applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
LookupBean lookupBean = (LookupBean) factory.getBean("lookupBean");
System.out.println("----------first time---------");
System.out.println("getCurrentTime:");
lookupBean.getCurrentTime().printCurrentTime();
System.out.println("createCurrentTime:");
lookupBean.createCurrentTime().printCurrentTime();
Thread.sleep(12345);
System.out.println("---------second time---------");
System.out.println("getCurrentTime:");
LookupBean lookupBean02 = (LookupBean) factory.getBean("lookupBean");
lookupBean02.getCurrentTime().printCurrentTime();
System.out.println("createCurrentTime:");
lookupBean02.createCurrentTime().printCurrentTime();
}
}