衆所周知,Spring容器默認情況下bean有singleton,如果我們有一個基於Spring框架的Web應用程序,那麼在這種情況下,我們是否真的需要實現Singleton設計模式掌握全球數據,而不是僅僅通過春天創建一個bean。Singleton設計模式vs Spring中的Singleton bean容器
如果我無法解釋我真正想要問什麼,請耐心等待。
衆所周知,Spring容器默認情況下bean有singleton,如果我們有一個基於Spring框架的Web應用程序,那麼在這種情況下,我們是否真的需要實現Singleton設計模式掌握全球數據,而不是僅僅通過春天創建一個bean。Singleton設計模式vs Spring中的Singleton bean容器
如果我無法解釋我真正想要問什麼,請耐心等待。
Spring中的單例範圍意味着這個bean將僅在Spring中實例化一次。與原型範圍(每次新實例)相比,請求範圍(每個請求一次),會話範圍(每個HTTP會話一次)。
單身職責範圍在技術上與單身設計模式有關。您不必將您的bean實現爲單例,以便將它們放入單例作用域中。
Spring中的singleton bean和singleton模式有很大不同。 Singleton模式表示,每個類加載器都會創建一個特定類的唯一實例。
Spring單例的範圍被描述爲「每個bean每個容器」。這是每個Spring IoC容器對單個對象實例的bean定義範圍。 Spring中的默認範圍是Singleton。
儘管默認範圍是單例,但您可以通過指定<bean ../>
元素的scope屬性來更改bean的範圍。
<bean id=".." class=".." scope="prototype" />
@ user184794:每個bean每個容器,這意味着在spring容器中只有一個類加載器。如果在spring容器中有兩個或多個類加載器,那麼每個類加載器都有自己的實例。它是否意味着「每個bean每個類加載器的每個容器」。請澄清! – 2011-07-28 10:59:23
我認爲這意味着Spring容器將使用它擁有的一個類加載器。你在Spring的機制之外做了什麼並不相關,也就是說,你可以創建自己的類加載器並根據需要創建一個類的實例,但是如果你通過Spring容器,它將不會創建多個實例 – inor 2014-05-08 08:36:32
然後他們並不像你說的那樣「非常不同」。唯一的區別是範圍 - Spring容器verses classloader – 2017-10-10 18:00:13
「singleton」在spring中使用bean factory獲取實例,然後緩存它;哪個單例設計模式是嚴格的,實例只能從靜態獲取方法中獲取,並且該對象永遠不能公開實例化。
Spring中的單例範圍意味着Spring環境中的單例。
Spring容器只是一次又一次地返回相同的實例,以便後續調用獲取bean。
如果bean的類被編碼爲singleton或不是,實際上如果類被編碼爲singleton的構造函數爲private,那麼Spring使用BeanUtils.instantiateClass(javadoc here)來設置構造函數訪問和調用它。
或者,我們可以在bean定義工廠方法屬性像在春天這個
<bean id="exampleBean" class="example.Singleton" factory-method="getInstance"/>
你確定你需要factory-method屬性嗎?我很確定Spring知道如何獲得一個實例,即使構造函數是私有的(可能會嘗試調用getInstance) – inor 2014-07-28 05:32:22
關於Spring如何調用私有構造函數[here]的相關討論(http://stackoverflow.com/a/7254617/ 2841265) – 2015-09-18 07:08:53
辛格爾頓豆類和類基於Singleton設計模式有很大的不同。
單例模式確保每個類加載器都會創建一個特定類的唯一實例,因爲Spring單例bean的範圍被描述爲「每個容器每個bean」。 Spring中的單例範圍意味着這個bean將僅在Spring中實例化一次。 Spring容器只是一次又一次地返回相同的實例,以便後續調用來獲取bean。
你是'java特立獨行',對不對?這會讓你的陳述「在...發現一個很好的解釋和例子」,這是一個不誠實的企圖隱瞞你正在鏈接到你自己的網站。無論如何,你的鏈接對於答案似乎並不重要。我將其刪除,以避免將答案作爲垃圾郵件刪除。在發佈更多鏈接到您的網站之前,請閱讀自我推銷的常見問題解答。還請注意,將您的網站鏈接放入您的個人資料中相當好。 – 2012-11-27 18:46:41
讓我們舉一個最簡單的例子:你有一個應用程序,你只需要使用默認的類加載器。你有一個類,無論出於何種原因,你決定它在應用程序中不應該有多個實例。 (想想幾個人在應用程序中工作的場景)。
如果您不使用Spring框架,Singleton模式可確保應用程序中不會有多於一個類的實例。這是因爲你不能通過執行'new'來實例化類的實例,因爲構造函數是私有的。獲得該類實例的唯一方法是調用該類的一些靜態方法(通常稱爲「getInstance」),該方法始終返回相同的實例。
說您在您的應用程序中使用Spring框架,只是意味着除了獲取類的實例(返回類的實例的新方法或靜態方法)的常規方法之外,您還可以詢問Spring爲你提供該類的一個實例,Spring將確保無論何時你要求它爲該類的一個實例,它總是會返回同一個實例,即使你沒有使用Singleton模式編寫該類。換句話說,即使這個類有一個公共構造函數,如果你總是向Spring請求這個類的一個實例,那麼Spring在你的應用程序的整個生命週期中只會調用這個構造函數。
通常情況下,如果你使用的是Spring,你應該只使用Spring來創建實例,並且你可以爲這個類創建一個公共構造函數。但是如果你的構造函數不是私有的,那麼你並不真正阻止任何人直接創建類的新實例,因爲它繞過了Spring。
如果您確實需要該類的單個實例,即使在您的應用程序中使用Spring並將Spring中的類定義爲單例,唯一的方法也是確保使用Singleton模式實現該類。這確保了會有單個實例,無論人們使用Spring來獲取實例還是繞過Spring。
EX:「每個容器每個bean」。
<bean id="myBean" class="com.spring4hibernate4.TestBean">
<constructor-arg name="i" value="1"></constructor-arg>
<property name="name" value="1-name"></property>
</bean>
<bean id="testBean" class="com.spring4hibernate4.TestBean">
<constructor-arg name="i" value="10"></constructor-arg>
<property name="name" value="10-name"></property>
</bean>
</beans>
public class Test {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("ws.xml");
TestBean teatBean = (TestBean) ac.getBean("testBean");
TestBean myBean1 = (TestBean) ac.getBean("myBean");
System.out.println("a : " + teatBean.test + " : " + teatBean.getName());
teatBean.setName("a TEST BEAN 1");
System.out.println("uPdate : " + teatBean.test + " : " + teatBean.getName());
System.out.println("a1 : " + myBean1.test + " : " + myBean1.getName());
myBean1.setName(" a1 TEST BEAN 10");
System.out.println("a1 update : " + teatBean.test + " : " + myBean1.getName());
}
}
public class TestBean {
public int test = 0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name = "default";
public TestBean(int i) {
test += i;
}
}
JAVA SINGLETON:
public class Singleton {
private static Singleton singleton = new Singleton();
private int i = 0;
private Singleton() {
}
public static Singleton returnSingleton() {
return singleton;
}
public void increment() {
i++;
}
public int getInt() {
return i;
}
}
public static void main(String[] args) {
System.out.println("Test");
Singleton sin1 = Singleton.returnSingleton();
sin1.increment();
System.out.println(sin1.getInt());
Singleton sin2 = Singleton.returnSingleton();
System.out.println("Test");
sin1.increment();
System.out.println(sin1.getInt());
}
彈簧單豆描述 '每容器每豆' 作爲。 Spring中的Singleton範圍意味着同一個內存位置的同一個對象將被返回到相同的bean ID。如果創建了多個相同類的不同id的bean,容器將不同的對象返回給不同的id。這就像一個鍵值映射,其中key是bean id,value是一個spring容器中的bean對象。 Singleton模式確保每個類加載器創建一個特定類的唯一實例。
我發現「per container per bean」很難理解。我會說「每個bean id一個bean」。讓我們用一個例子來理解它。我們有一個Bean類Sample。我從這個類的bean定義兩個bean,如:
<bean id="id1" class="com.example.Sample" scope="singleton">
<property name="name" value="James Bond 001"/>
</bean>
<bean id="id7" class="com.example.Sample" scope="singleton">
<property name="name" value="James Bond 007"/>
</bean>
所以,當過我嘗試獲取ID爲「ID1」的bean時,Spring容器將創建一個豆,緩存並返回同一個bean曾經引用過id1的地方。如果我嘗試使用id7來獲取它,則將從Sample類創建另一個bean,並且每次使用id7引用時都會緩存並返回。
這對單例模式來說不太可能。在Singlton模式中,每個類加載器總是創建一個對象。但在春天,許多對象正在爲同一個班級創建。然而,在Spring中,作爲Singleton的作用域爲相同的ID返回相同的對象。 Reference
糾正我,如果我錯了,所以根據你,如果我需要實現任何對象作爲單身人士,所以不需要實現單身模式。使用Spring創建該bean將起作用。我現在有點困惑,我的理解與Spring框架中的Singleton設計模式和Singleton範圍有關。 – Peeyush 2010-04-14 17:08:52
Spring不會強制您使用Singleton模式。 – lexicore 2010-04-14 17:19:20