專案中,報表匯出涉及到了在同乙個類的兩個不同方法中,都有相同的查詢資料庫的操作,乙個方法是用於獲取內容,乙個是用於獲取條數的,大概類似於這樣:
@service
public
class
myreportexporter
extends
abstractreportexporter
@override
protected
intgetcount(param param)
}
由於是繼承的父類統一處理,因此沒辦法單獨優化這個步驟。在父類的統一處理過程中,會多次呼叫getcount方法,這樣每處理一次,就需要多次查詢資料庫。
這是會想到,可以用私有全域性變數將查詢結果存起來。
在spring中,@service預設都是單例的。用了私有全域性變數,若不想影響下次請求,就需要用到原型模式,即@scope(「prototype」)
所謂單例,就是spring的ioc機制只建立該類的乙個例項,每次請求,都會用這同乙個例項進行處理,因此若存在全域性變數,本次請求的值肯定會影響下一次請求時該變數的值。
原型模式,指的是每次呼叫時,會重新建立該類的乙個例項,比較類似於我們自己自己new的物件例項。
通過檢視@scope我們可以看到,預設的模式:singleton
public @inte***ce
scope
通過如下方式,可以將該類設定為原型模式
@service
@scope("prototype")
public
class
myreportexporterextends
abstractreportexporter
在進行以上改動後,執行發現並沒有生效,依然是乙個例項。這說明只加乙個@scope註解還不夠。
在呼叫改service的controller層,是這樣注入的:
@autowired
private myreportexporter myreportexporter;
而controller同樣是預設單例的,因此只例項化了乙個controller物件,在其中依賴注入的myreportexporter物件也就只會例項化一次。
在不想改變controller單例模式的情況下,可以如下修改:
放棄使用@autowired方式,改用getbean方式:
private
可以自己寫個spring工廠類,如下:
import org.springframework.beans.bean***ception;然後,通過如下方式呼叫:import com.quhuhu.cesar.common.utils.logutils;
public
class
springbeanfactory
implements
private
@override
public
void
}/**
* 獲取某個bean的物件
*/public
static
t getbean(classclazz) catch (exception e)
return
null;
}}
springbeanfactory.getbean(myreportexporter.class).dosth()
修改後,執行ok,達到自己想要的結果。
spring中依賴注入的預設物件為單例形式,@scope(「prototype」)註解可以將其改變為原型模式。
改變底層(如service層)的物件為原型時,同時改變上層呼叫層(如controller層)的呼叫方式,原型模式才會生效。
JavaScript中原型和原型鏈
原型 prototype 為其他物件提供共享屬性的物件。每個函式都有乙個原型 prototype 屬性,這個屬性是乙個指標,指向乙個物件,這個物件包含特定例項共享的一些屬性和方法。以例服人 這個例子說明了原型物件是共享的,並且是乙個指標,並且物件的例項中也有指向prototype指向物件的指標。fu...
js中原型和原型鏈
let hd new object object.prototype.show function function getname console.dir getname console.log getname.prototype.proto getname.proto proto true con...
js中原型物件詳解
我們先來了解一下,js使用原型物件的作用是什麼?回答 在使用自定義建構函式建立物件情況下,在例項化多個物件時,可能有很多方法或者屬性相同,比如乙個人的物件建構函式,那麼人都有會跑的方法一樣,都有10個拇指等等屬性,這個人物件的方法,你例項方法的時候都得一一建立記憶體空間,這樣太耗資源,那麼就需要乙個...