Spring的Sope是什么
Scope籍茧,也稱作用域疑俭,在 Spring IoC 容器是指其創(chuàng)建的 Bean 對(duì)象相對(duì)于其他 Bean 對(duì)象的請(qǐng)求可見范圍遥巴。在 Spring IoC 容器中具有以下幾種作用域:基本作用域(singleton分飞、prototype)恶导,Web 作用域(reqeust、session浸须、globalsession)惨寿,自定義作用域。
-
singleton
即ConfigurableBeanFactory.SCOPE_SINGLETON
,單例模式删窒,也為默認(rèn)模式;
-
prototype
即ConfigurableBeanFactory.SCOPE_PROTOTYPE
,多例模式;
-
request
即WebApplicationContext.SCOPE_REQUEST
,表示在一次http請(qǐng)求中裂垦,被注解的Bean都是同一個(gè)Bean,不同的請(qǐng)求是不同的Bean;
-
sesson
即WebApplicationContext.SCOPE_SESSION
,表示在一次http會(huì)話中肌索,被注解的Bean都是同一個(gè)Bean蕉拢,不同的會(huì)話是不同的Bean;
prototype陷阱
正常情況下singleton
為單例,prototype
為多例诚亚,若直接在入口位置即使用prototype
屬性晕换,那么對(duì)應(yīng)的實(shí)例確實(shí)會(huì)有多個(gè)。但是若prototype
修飾的類對(duì)象為其他singleton
修飾的對(duì)象對(duì)應(yīng)的屬性站宗,則prototype
起不到真正的想要結(jié)果闸准。因?yàn)楸緫?yīng)該為多例的對(duì)象,被單例對(duì)象首次加載的時(shí)候已經(jīng)賦予在內(nèi)存里.
@Scope("prototype")的正確用法——解決Bean的多例問題
Spring中原型prototype的準(zhǔn)確使用
但實(shí)際上prototype
并不是不對(duì)梢灭,也不是出了問題夷家,而是我們的使用方式有問題蒸其。
如何處理prototype屬性不起效的問題
- 正常情況下,直接使用
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
或@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
库快,可以實(shí)現(xiàn)真正的多例模式避归。但是若業(yè)務(wù)內(nèi)存在異步操作寥枝,且請(qǐng)求相關(guān)的http丟失,則會(huì)報(bào)錯(cuò).
Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
I am getting the above error when i am injecting a spring dependency and using it inside MessageListener bean
- 直接使用
SpringBeanUtil
獲取對(duì)應(yīng)Bean;
對(duì)于嵌套Scope
情形曲横,通過getApplicationContext().getBean()
方式生年,獲取bean對(duì)象悔据,若對(duì)象為prototype
琳猫,則會(huì)按照Bean的生成策略抵知,生成多例對(duì)象。
- 上面的兩種方式阳啥,要么可能存在問題,要么感覺不怎么優(yōu)雅财喳。這里還有一個(gè)方法察迟。
@Autowired
ObjectFactory<BalanceLogic> balanceLogicFactory
直接使用
BalanceLogic balanceLogic = balanceLogicFactory.getObject();