瘋狂
STANDING ON THE SHOULDERS OF GIANTS
posts - 481, comments - 486, trackbacks - 0, articles - 1
BlogJava
::
首頁
::
新隨筆
::
聯系
::
聚合
::
管理
注意spring, singleton不single! ?
Posted on 2010-08-30 00:41
瘋狂
閱讀(6909)
評論(12)
編輯
收藏
所屬分類:
java
、
spring
、
web
spring的singleton真的會在整個應用中創建單一的對象嗎?非也,他只會在內部springframework的一個applicationContext上下文中保持單利,但是如果有兩個applicationContext呢?
首先看以下實例 :
首先定義一個bean 并注冊為單利,非懶加載對象:
package
com.joe.service;
public
class
TestService
{
public
TestService()
{
System.out.println(
"
create TestService
"
);
}
}
配置:
<
bean id
=
"
testservice
"
class
=
"
com.joe.service.TestService
"
scope
=
"
singleton
"
lazy
-
init
=
"
false
"
></
bean
>
測試代碼:
private
static
ApplicationContext context1;
private
static
ApplicationContext context2;
static
{
context1
=
new
ClassPathXmlApplicationContext(
new
String[]{
"
classpath:spring-bean_*.xml
"
});
context2
=
new
ClassPathXmlApplicationContext(
new
String[]{
"
classpath:spring-bean_*.xml
"
});
}
public
static
void
main(String[] args)
throws
SQLException, IOException {
System.out.println(
"
context1 中 testservice 是否單利?
"
+
context1.isSingleton(
"
testservice
"
));
TestService service
=
(TestService) context1.getBean(
"
testservice
"
);
System.out.println(service);
System.out.println(
"
context2 中 testservice 是否單利?
"
+
context2.isSingleton(
"
testservice
"
));
TestService service2
=
(TestService) context2.getBean(
"
testservice
"
);
System.out.println(service2);
System.out.println(service);
System.out.println(
"
context1 中 testservice 是否和context2 中 testservice 是一個對象?
"
+
(service
==
service2));
//
關鍵地方 兩個ApplicationContext 中拿 到的是否是一個對象?
}
結果:
create TestService
create TestService
context1 中 testservice 是否單利?
true
com.joe.service.TestService@54c4ad
context2 中 testservice 是否單利?
true
com.joe.service.TestService@13c7378
com.joe.service.TestService@54c4ad
context1 中 testservice 是否和context2 中 testservice 是一個對象?
false
很明顯在一個jvm應用中出現兩個被標注為單利的實例。
spring內部通過上下文中的集合來管理對象,核心為beanFactory,而非通過asm等來動態改變類結構來控制類的scope。
我們跟著源碼來看看:
在調用new ClassPathXmlApplicationContext實際上調用了
this(configLocations, true, null);其中的true代表要刷新上下文:而最終的refresh是這樣的
if
(hasBeanFactory())
{
destroyBeans();
closeBeanFactory();
}
但是很費解的是hasBeanFactory的判斷:
protected
final
boolean
hasBeanFactory()
{
synchronized
(
this
.beanFactoryMonitor)
{
return
(
this
.beanFactory
!=
null
);
}
}
其中的this.beanFactory是ClassPathXmlApplicationContext的實例的屬性private DefaultListableBeanFactory beanFactory;
不用說this.beanFactory==null因為我們new了一個ClassPathXmlApplicationContext , beanFactory也沒有初始化操作,也沒有parentContext (因為我根本不知道有沒有parentContext)而beanFactory也不是static的。
也就是說在第二次new ClassPathXmlApplicationContext的時候并不會refresh beanFactory 當然就會有兩個單利的實例。
此問題在項目中出現,當時由于一個同事在自己的一個類里面的static區域new了ClassPathXmlApplicationContext用來測試忘記刪掉, 而我們的所有類又是通過web容器來加載,結果就導致項目中出現單利對象出現兩個的問題,結果害的那個苦啊!
希望大家在實際項目中注意到,也希望大家跟帖討論下,我分析的是否正確,大家實際項目中有沒有解決方案來避免這樣的問題!
評論
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 10:01 by
隔葉黃鶯
謝謝,又了解到一點知識,范圍是基于 applicationContext,而不是 JVM。其實通常的單例,我們要更嚴格的來講也不能說是基于 JVM,而是基于 ClassLoader 的。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 10:38 by
forest
我測試了一下,發現兩個test是相同的。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 10:58 by
@joe
@forest
能提供下測試代碼看看嗎?
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 11:11 by
Lancelot
人家的singleton本來就是相對于容器的。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 11:43 by
@joe
@Lancelot
但是真正的項目中要的是真正的單利,我感覺這種思想脫離了實際應用。給項目帶來了麻煩這是事實。我不知道spring是處于何種思想?希望兄臺給個解釋!
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 11:57 by
@joe
查看spring的文檔然后了解到實質,請看一下文檔(來自spring官方文檔)
3.4.1. The singleton scope
When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.
請注意一下內容:
**********************************************
Please be aware that Spring's concept of a singleton bean is quite different from the Singleton pattern as defined in the seminal Gang of Four (GoF) patterns book. The GoF Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader. The scope of the Spring singleton is best described as per container and per bean.
*********************************************
This means that if you define one bean for a particular class in a single Spring container, then the Spring container will create one and only one instance of the class defined by that bean definition. The singleton scope is the default scope in Spring
當然spring是per container and per bean.
也就是(Scopes a single bean definition to a single object instance per Spring IoC container.
);
唉 以后注意。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 12:02 by
@joe
@@joe
但為什么不使用GoF Singleton 呢??????
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 12:29 by
anders
@joe
但是真正的項目中要的是真正的單利,我感覺這種思想脫離了實際應用。給項目帶來了麻煩這是事實。我不知道spring是出于何種思想?希望兄臺給個解釋!
...
有點無語。
第一joe沒有弄清出spring提供單例范圍。spring單例基于container的。
第二joe還沒有弄清項目中單例的范圍,“什么叫真正的項目真正的單例”,以偏蓋全——以自己項目的需求覆蓋全部的需求。
對于一個J2EE來說,如果運行在應用服務器下,一個應用服務器可以同時支持多個應用,單例的范圍就應該是每個應用一個單例,就是spring的考慮,不能是
兩個應用使用同一個單例,會出很多問題比如classload的問題。如果確實需要,則應自己擴展spring的scope,采用jndi的方式獲取單例。
“什么叫真正的項目真正的單例”,單例是基于JVM的,還是基于OS的,還是基于內網的,還是基于整個互聯網的。
基于JVM的給用靜態變量;基于OS的給借助OS特性,比如文件系統;基于內網的和互聯網的就根復雜了。。。。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-30 13:22 by
@joe
@anders
首先感謝anders的恢復 !,讓人更深入的了解了Singleton !
但是我的情況就是在一個應用中出現了這樣的問題,既然一個應用中可以new 多個applicationContext,為什么不加以控制呢!我感覺不應該研發自己去注意這些東西,應該對于一個應用有一個Global Application足以,如果再new application的時候 直接指向前一個applicationContext!這樣Singleton 在一個應用中應該可以得到解決!
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-31 11:16 by
xylz
@@joe
anders說的很明白了,spring是基于container的!這與單例的作用范圍其實沒有關系。。。
#
re: 注意spring, singleton不single! ?
回復
更多評論
2010-08-31 13:44 by
@joe
@xylz
spring是基于container的.我明白!
但是脫離實際項目談這些是沒有用,給項目帶來風險的東西,都是值得考慮,值得注意的,概念誰都懂!
#
re: 注意spring, singleton不single! ?
回復
更多評論
2013-12-21 16:33 by
zb
爭論有意義嗎,說明白不就成了,孔已己似的.
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關文章:
JAVA Thread Dump 分析綜述
關于java RMI在多網卡下(或者啟動360,百度,騰訊等wifi共享下)無法連接問題(java.rmi.ConnectException: Connection refused to host: xx)
Quartz+Spring的集群配置(轉)
java.awt.headless=true
dom4j通過xpath查詢xml (轉)
深入探討 Java 類加載器
Java ClassLoader基礎知識
synchronized 要注意的地方
關于java.lang.IllegalMonitorStateException
ThreadPoolExecutor運轉機制詳解 .
Powered by:
BlogJava
Copyright © 瘋狂
日歷
<
2010年8月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
公告
公眾號:
QQjava交流群:
51374316
留言簿
(11)
給我留言
查看公開留言
查看私人留言
隨筆分類
all 生活雜談(16)
android(18)
apache項目(20)
chart(1)
concurrent(5)
database(70)
dwr(3)
flex(6)
hibernate(25)
java (135)
javafx(2)
javascript
java安全(8)
java性能(19)
jbpm(1)
jquery(4)
linux(17)
lucene(1)
netty(3)
nginx(1)
others(2)
questions(31)
questions_hander(28)
spring(32)
struts(9)
swing
UML(2)
unix(13)
web(45)
webservice(9)
xml(5)
敏捷(6)
方法論(28)
架構(21)
測試(1)
緩存
網絡通訊(9)
讀代碼(6)
項目管理(19)
相冊
我的相冊
搜索
積分與排名
積分 - 2840194
排名 - 2
最新隨筆
1.? 后續內容請移步公眾號“duomi88”
2.?Netty百萬級推送服務(轉)
3.?Netty 概述(轉)
4.?Netty優雅退出機制和原理(轉)
5.?使用JavaMail SearchTerm 收取郵件
6.?JAVA Thread Dump 分析綜述
7.?oracle 索引字段包含date類型,使用spring jdbc更新時不走索引,而是走table access full的問題
8.?FTP主動模式和被動模式的比較(轉載)
9.?關于java RMI在多網卡下(或者啟動360,百度,騰訊等wifi共享下)無法連接問題(java.rmi.ConnectException: Connection refused to host: xx)
10.?(轉)Oracle數據庫如何授權收費(Database Licensing)
11.? 成功的 Web 應用系統性能測試 (轉載)
12.?It is indirectly referenced from required .class file異常
13.?(轉)svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
14.?automation服務器不能創建對象 解決辦法
15.?ERROR: transport error 202: gethostbyname: unknown host 解決辦法
16.?JavaScript 跨瀏覽器事件處理(轉)
17.?函數聲明 VS 函數表達式(轉)
18.?ORA-06548錯誤
19.?項目規劃與管理記錄2
20.?tmpFile.renameTo(classFile) failed
21.?redhat6.4 64位安裝rlwrap
22.?ora-01031:insufficient privileges
23.?mysql遠程連接問題 Access denied for user 'root'@' ip ' (using password: YES)
24.?dbcp重連(轉)
25.?解決Vmware Workstation上安裝Linux系統不能SSH遠程連接的問題
26.?URL最大長度限制(轉)
27.?用MyEclipse測試發送email時報java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
28.?我應該采用哪一種 WSDL 樣式?(轉載)
29.?linux 掛載ntfs usb 出現mount: unknown filesystem type 'ntfs'
30.?11g oracle 用戶密碼過期問題
最新評論
1.?re: Oracle物化視圖創建全過程(轉)
評論內容較長,點擊標題查看
--ya
2.?re: Oracle物化視圖創建全過程(轉)
評論內容較長,點擊標題查看
--ya
3.?re: 11g oracle 用戶密碼過期問題
問問
--是是是
4.?re: mysql遠程連接問題 Access denied for user 'root'@' ip ' (using password: YES)
asdfsadf
--asdf
5.?re: struts(il8n)實現國際化的一個例子
在啥地方
--正常
主站蜘蛛池模板:
久久亚洲国产成人亚
|
亚洲国产精品一区二区久久hs
|
亚洲综合免费视频
|
国产免费高清69式视频在线观看
|
亚洲AV无码精品蜜桃
|
亚洲色偷偷偷网站色偷一区
|
亚洲最大激情中文字幕
|
亚洲国产成人久久精品99
|
成人午夜视频免费
|
香蕉视频在线观看免费国产婷婷
|
成人免费在线看片
|
在线观看免费视频资源
|
久久久免费的精品
|
亚洲视频在线观看免费视频
|
性短视频在线观看免费不卡流畅
|
免费无码中文字幕A级毛片
|
伊人久久免费视频
|
亚洲精品视频在线免费
|
成年性生交大片免费看
|
日韩在线免费电影
|
在线精品亚洲一区二区小说
|
亚洲av无码乱码国产精品
|
亚洲六月丁香六月婷婷色伊人
|
在线观看免费中文视频
|
最新欧洲大片免费在线
|
亚洲国产成人VA在线观看
|
精品久久久久久亚洲
|
亚洲jjzzjjzz在线观看
|
一区视频免费观看
|
国产免费毛不卡片
|
亚洲午夜成人精品电影在线观看
|
亚洲天堂中文字幕
|
国产亚洲精品美女久久久久久下载
|
免费国产叼嘿视频大全网站
|
午夜爱爱免费视频
|
亚洲男人的天堂在线
|
一级毛片视频免费
|
女人18毛片水真多免费播放
|
久久久久亚洲精品无码系列
|
色吊丝性永久免费看码
|
亚洲色欲www综合网
|