欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring單例如何改多例

 更新時間:2022年01月19日 14:56:34   作者:彭珂?zhèn)€人網(wǎng)  
這篇文章主要介紹了spring單例如何改多例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

spring單例改多例

單例:就像你一生只有一個老婆。也就是對象始終是同一個。

多例:就像你一生有好多個老婆。也就是對象每次都是新的。

spring默認是單例模式(就每個請求都是用的同一對象,對于dao層肯定是棒棒的),但是有的時候,我們需要每個請求都

產(chǎn)生一個新的對象,就如做微信小程序,用scoket、不可能一直都用一個來接收的,因為需要分配房間,所以需要使用到多例。

對于struts2來說,action必須用多例,因為action本身含有請求參數(shù)的值,即可改變的狀態(tài);

而對于STRUTS1來說,action則可用單例,因為請求參數(shù)的值是放在actionForm中,而非action中的;

配置某個類為多例:

<bean id="user" class="modle.User" scope="prototype"> ?</bean>

但是比如service配置的是多例、dao又是單例,那肯定不行了,因為不能自動注入。

所以需要獲得一個新的dao實例,但是手動new的都不可以,那么就借助通過實現(xiàn) BeanFactoryAware 接口來獲得factory

附加自己待測試

public class userService implements BeanFactoryAware{ ??
? private UserDao userDao;
? private BeanFactory factory;
? public void userService (){
? ? this.userDao= (UserDao)factory.getBean("userDao");
? ? userDao.work();
? }
? public UserDao getUserDao() {
? ? ? ? return userDao;
? }
public void setBeanFactory(BeanFactory f) throws BeansException {
? ? factory = f;
? }
?
}

spring單例、多例使用方法

今天聊聊單例和多例。只想看spring管理的實例有哪些模式,直接看最后。

相信大部分使用java 做web開發(fā)的開發(fā)人員都用過spring。spring功能最基礎(chǔ)功能就是IoC(Inversion of control——控制反轉(zhuǎn))、AOP(Aspect Oriented Programming——面向切面編程)。其中IoC核心是DI(Dependency injection——依賴注入)。

我們最開始寫項目自然而然的是沒有框架,生寫!但代碼多了之后,發(fā)現(xiàn)有很多代碼,可以抽成公共方法。有些又可以抽成一個類。而有些類又是貫穿整個項目生命周期始終的,而且往往這些類的初始化方法很復(fù)雜且重要。那怎么辦,總不能每次使用的時候初始化一遍吧,這樣很耗編碼時間不說,還很占用計算機性能。于是,工廠模式應(yīng)運而生。通過工廠模式獲取各個重要的實例對象。這樣就帶來一個問題,怎樣保證實例只創(chuàng)建一次呢?單例模式應(yīng)運而生。于是,我們常用的框架spring就成了。

然而需求的發(fā)展往往不是單一技術(shù)能很好解決的。單例、依賴注入固然好。但是也讓我們的開發(fā)模式陷入一種定式。即controller、service、dao這樣雖然是快速規(guī)范的劃分,但是往往一些復(fù)雜的邏輯只在service或者controller中寫會有大量的私有方法、或者一個方法幾百上千行。整個業(yè)務(wù)操作的生命周期局限在一個方法內(nèi)。并不能好好利用面向?qū)ο蟮乃枷?,寫到最后完全就是面向過程編程。一旦邏輯復(fù)雜,那方法寫的簡直慘不忍睹,而且局限于方法的生命周期,很多參數(shù)可能會多次調(diào)用數(shù)據(jù)庫查同一個數(shù)據(jù)。那么有什么辦法能改變這個局面呢?歷史總會給我們答案。

自新世紀之初提出“領(lǐng)域驅(qū)動設(shè)計”(DDD)以來,這玩意一直不受重視,不僅玄之又玄的理論很少有人去專研,而且所謂“敏捷開發(fā)”的盛行,也不適合DDD。但這里并不介紹DDD,說一說DDD的充血模型要在傳統(tǒng)數(shù)據(jù)驅(qū)動的業(yè)務(wù)中使用將面臨的首要問題——單例如何注入進充血模型。

比如,我有個User對象,而對象的保存查詢操作是與數(shù)據(jù)庫操作。我并不想讓User是一個干癟的值對象,而是讓他具備行為,是一個真正有血有肉的充血模型。那么saveUser(User)這樣的方法就不再由Dao提供,而是應(yīng)該由user.save()替代。熟悉JPA的同學(xué)肯定想到了。jpa支持對象操作替代傳統(tǒng)的repository操作。例如典型的user中的List<Role> roles屬性作為關(guān)聯(lián)查詢的屬性。如果設(shè)置級聯(lián)查詢?yōu)閼屑虞d,那么jpa只在調(diào)用user.getRoles()方法執(zhí)行的時候發(fā)送sql查詢對應(yīng)的role。這是因為jpa代理了user實體對象,而且這也有個問題。如果被jpa代理的對象調(diào)用toString()方法,獲取roles屬性打印時會觸發(fā)jpa操作。但這時可能已經(jīng)不屬于jpa Entity的生命周期了。踩過坑的朋友肯定遇到過打印日志報了莫名的jpa異常,百思不得其解吧。

況且我們想要的不只是這些。我們可能有些其他的被sqring單例管理的對象方法需要在不同的實例對象中使用。例如:user想要發(fā)送數(shù)據(jù)到遠程。那么user.send()可就不歸jpa管了。此時如果要想讓user能做這個事情必然只能通過spring上下文獲取被spring管理的類。聰明的小伙肯定想到了。我讓user也被spring管理起來,不就可以注入了嗎?是的,但是一旦被spring管理默認就是單例的??偛荒苊總€user都是同一個吧。其實spring可以設(shè)置多例的,只是用的人很少。在加有@componet之類注解(@service、@bean...等)受spring管理的類上再加上注解@scope(“prototype”)那么被spring管理的類就是多例的。稍微麻煩點的是,要想獲取多例必須通過spring上下文獲取。如果直接注入,那么注入的user還是只是那一個。相信各位一定都看過@scope(“prototype”)這種寫法吧。但spring其實提供了常量,@scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE),常量可以防止寫錯那長串單詞。有了多例,我們有血有肉的User對象寫起來就方便了許多。

為什么我們要這么做呢?“把權(quán)力關(guān)進籠子”,這句話在編程界就是強類型、常量、枚舉這些來體現(xiàn)的。同樣,DDD也是把權(quán)力鎖進領(lǐng)域?qū)ο?。避免隨心所欲的service、隨心所欲的repository導(dǎo)致代碼后期維護成為爬“屎山”。

spring支持的模式

1.ConfigurableBeanFactory.SCOPE_SINGLETON——單例

2.ConfigurableBeanFactory.SCOPE_PROTOTYPE——多例

擴展模式

3.WebApplicationContext.SCOPE_APPLICATION

4.WebApplicationContext.SCOPE_GLOBAL_SESSION

5.WebApplicationContext.SCOPE_SESSION

6.WebApplicationContext.SOCPE_REQUEST

以上擴展模式看名字都能明白不做多介紹了。希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論