2010-04-14 2 views
74

Как мы все знаем, у нас есть фасоль как одиночный по умолчанию в контейнере Spring, и если у нас есть веб-приложение на основе Spring Framework, тогда в этом случае нам действительно нужно реализовать шаблон проектирования Singleton для хранения глобальных данных, а не для создания боба по весне.Шаблон дизайна Singleton vs Singleton beans в контейнере весны

Прошу вас, если я не могу объяснить, что я на самом деле хотел спросить.

ответ

9

Singleton scope in Spring означает, что этот компонент будет создан только один раз весной. В отличие от области прототипа (новый экземпляр каждый раз), область запроса (один раз на запрос), область сеанса (один раз за сеанс HTTP).

Одиночная область Singleton технически связана с шаблоном дизайна синглтона. Вам не нужно реализовывать свои бобы как синглтоны, чтобы они могли быть помещены в одноэлементную область.

+0

Исправьте меня, если я ошибаюсь в соответствии с вами, если мне нужно реализовать какой-либо объект как singleton, поэтому нет необходимости реализовывать одноэлементный шаблон. Создание этого компонента с использованием Spring будет работать.Я немного смущен теперь с моим пониманием, связанным с шаблоном Singleton Design и областью Singleton в Spring framework. – Peeyush

+1

Весна не заставляет вас использовать шаблон Singleton. – lexicore

46

Одноэлементный боб весной и одноэлементный узор совершенно разные. Шаблон Singleton говорит, что один экземпляр определенного класса будет создан для каждого загрузчика классов.

Объем синглтона весны описывается как «для каждого контейнера в бине». Это объем определения bean-объекта для экземпляра одного объекта в контейнере Spring IoC. По умолчанию в Spring используется Singleton.

Несмотря на то, что область по умолчанию является одиночной, вы можете изменить область действия компонента, указав атрибут области <bean ../>.

<bean id=".." class=".." scope="prototype" /> 
+7

@ user184794: каждый контейнер в bean-компоненте, то есть в весеннем контейнере есть только один загрузчик классов. Если в весеннем контейнере есть два или более загрузчика классов, то каждый загрузчик классов будет иметь собственный экземпляр. Означает ли это «для каждого контейнера для каждого загрузчика классов». любезно уточните !! –

+4

Я думаю, это означает, что в контейнере Spring будет использоваться один классный загрузчик, которому он владеет. то, что вы делаете вне механизма Spring, не имеет значения, т. е. вы можете создавать свои собственные загрузчики классов и создавать столько экземпляров класса, сколько хотите, но если вы пройдете через контейнер Spring, он не будет создавать более одного экземпляра – inor

+0

Тогда они не «совсем другие», как вы заявляете. Единственное различие - сфера - Spring container verses classloader –

1

«singleton» весной использует экземпляр bean factory get, затем кеширует его; который шаблон дизайна singleton строго, экземпляр может быть извлечен только из статического метода get, и объект никогда не может быть публично инстанцирован.

25

Singleton scope весной означает один экземпляр в контексте весны.
Весенний контейнер просто возвращает тот же экземпляр снова и снова для последующих вызовов, чтобы получить компонент.



И весна не беспокоит, закодирован ли класс компонента как одиночный или нет, на самом деле, если класс закодирован как singleton, конструктор которого является приватным, Spring использует BeanUtils.instantiateClass (javadoc here), чтобы установить конструктор для доступа и вызова.

В качестве альтернативы, можно использовать атрибут заводского метода в определении боба как этого

<bean id="exampleBean" class="example.Singleton" factory-method="getInstance"/> 
+1

вы уверены, что вам нужен атрибут factory-method? Я уверен, что Spring знает, как получить экземпляр, даже если конструктор является закрытым (возможно, он пытается вызвать getInstance) – inor

+0

Связанная дискуссия о том, как Spring ссылается на частный конструктор [здесь] (http://stackoverflow.com/a/7254617/ 2841265) –

2

Singleton бобы весна и классы на основе шаблона проектирования Singleton совершенно различны.

Шаблон Singleton гарантирует, что один экземпляр определенного класса будет когда-либо создан для каждого загрузчика классов, где область одного синтаксического компонента Spring описывается как «для каждого контейнера в бине». Singleton scope in Spring означает, что этот компонент будет создан только один раз к весне. Контейнер Spring просто возвращает один и тот же экземпляр снова и снова для последующих вызовов для получения компонента.

+10

Вы "java maverick", не так ли? Это сделало бы ваше заявление «Найденное хорошее объяснение и пример в ...» нечестной попыткой скрыть, что вы связываетесь с собственным сайтом. Во всяком случае, ваша ссылка не очень важна для ответа. Я удаляю его, чтобы избежать удаления ответа как спама. Пожалуйста, прочитайте FAQ по Self-Promotion, прежде чем размещать какие-либо ссылки на ваш сайт. также обратите внимание, что для вас очень удобно разместить ссылку на свой сайт в своем профиле. –

15

Давайте рассмотрим простейший пример: у вас есть приложение, и вы просто используете загрузчик классов по умолчанию. У вас есть класс, который по какой-то причине вы решаете, что в приложении не должно быть более одного экземпляра. (Подумайте о сценарии, когда несколько человек работают над частями приложения).

Если вы не используете фреймворк Spring, шаблон Singleton гарантирует, что в вашем приложении не будет более одного экземпляра класса. Это связано с тем, что вы не можете создавать экземпляры класса, выполняя «новое», потому что конструктор является закрытым. Единственный способ получить экземпляр класса - вызвать некоторый статический метод класса (обычно называемый «getInstance»), который всегда возвращает один и тот же экземпляр.

Говоря о том, что вы используете фреймворк Spring в своем приложении, просто означает, что помимо обычных способов получения экземпляра класса (новые или статические методы, возвращающие экземпляр класса), вы также можете задать Spring, чтобы получить экземпляр этого класса, и Spring обеспечит, что всякий раз, когда вы запрашиваете экземпляр этого класса, он всегда возвращает тот же экземпляр, даже если вы не пишете класс с использованием шаблона Singleton. Другими словами, даже если класс имеет открытый конструктор, если вы всегда запрашиваете Spring для экземпляра этого класса, Spring будет вызывать этот конструктор только один раз в течение срока действия вашего приложения.

Обычно, если вы используете Spring, вы должны использовать Spring только для создания экземпляров, и у вас может быть открытый конструктор для класса. Но если ваш конструктор не является частным, вы на самом деле не мешаете никому создавать новые экземпляры класса напрямую, минуя Spring.

Если вам действительно нужен один экземпляр класса, даже если вы используете Spring в своем приложении и определяете класс в Spring как одноэлементный, единственный способ гарантировать, что он также реализует класс с использованием шаблона Singleton. Это гарантирует, что будет один экземпляр, если люди используют Spring для получения экземпляра или обхода Spring.

1

EX: «за контейнер в фасоли».

 <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()); 
    } 
+0

<фасоли класс = "com.spring4hibernate4.TestBean"> \t \t <Конструктор-Arg имя = "я" значение = "1"> \t \t <имя = "имя" значение свойства =» 1-имя "> \t \t <фасоли класс =" com.spring4hibernate4.TestBean "> \t \t <конструктор-Arg имя =" я»значение = "10"> \t \t \t – Hariprasad

0

Спринга одноэлементная фасоль описываются как "за контейнер в боб. Singleton scope весной означает, что тот же самый объект в том же месте памяти будет возвращен одному и тому же идентификатору. Если вы создаете несколько компонентов из разных идентификаторов одного и того же класса, тогда контейнер будет возвращать разные объекты в разные идентификаторы. Это похоже на сопоставление ключевых значений, где ключ является идентификатором bean и значением является объект bean в одном весеннем контейнере. Где в качестве шаблона Singleton гарантируется, что один экземпляр определенного класса будет создан для каждого загрузчика классов.

1

Я нахожу «в контейнере за боб» трудно понять. Я бы сказал, «один bean-компонент для bean id». У вас есть пример, чтобы понять это. У нас есть образец класса компонента. Я определил два зерна из этого класса в определении фасоли, как:

<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> 

Так что, когда я когда-либо попытаться получить боб с идентификатором «ID1», пружинный контейнер будет создавать один компонент, кэш его и вернуть тот же боб где когда-либо ссылались на id1. Если я попытаюсь получить его с id7, другой компонент будет создан из класса Sample, тот же будет кэшироваться и возвращаться каждый раз, когда вы ссылаетесь на него с id7.

Это маловероятно, если шаблон Singleton. В Singlton всегда создается один объект для каждого загрузчика классов. Но весной многие объекты создаются для одного и того же класса. Однако весной, делая область как Singleton, возвращает тот же объект для одного и того же идентификатора. Reference

Смежные вопросы