Шаблон проектирования Singleton vs Singleton beans в контейнере Spring

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

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

Ответ 1

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

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

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

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

Ответ 2

Область Singleton в spring означает один экземпляр в контексте spring.
Контейнер Spring возвращает один и тот же экземпляр снова и снова для последующих вызовов для получения bean.


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

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

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

Ответ 3

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

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

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

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

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

Ответ 4

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

Синглтонская область технически связана с шаблоном проектирования singleton. Вам не нужно реализовывать ваши beans как синглтоны для их размещения в области Singleton.

Ответ 5

Я нахожу "на контейнер на боб" трудным для понимания. Я бы сказал "один бин на идентификатор бина". Пусть есть пример, чтобы понять это. У нас есть образец класса бобов. Я определил два 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>

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

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

Существует очень фундаментальное различие между ними. В случае шаблона разработки Singleton для одного classLoader будет создан только один экземпляр класса, в то время как в случае синглтона Spring это не так, как в последующем создан один экземпляр общего компонента для данного идентификатора для контейнера IoC.

Например, если у меня есть класс с именем "SpringTest" и мой XML файл выглядит примерно так:

<bean id="test1" class="com.SpringTest" scope="singleton">
        --some properties here
</bean>    
<bean id="test2" class="com.SpringTest" scope="singleton">
        --some properties here   
</bean>

Так что теперь в основном классе, если вы проверите ссылку на вышеупомянутые два, он вернет false, как указано в документации Spring:

Когда компонент является одноэлементным, будет управляться только один общий экземпляр компонента, и все запросы для компонентов с идентификатором или идентификаторами, соответствующими определению компонента, приведут к тому, что один конкретный экземпляр компонента будет возвращен контейнером Spring.

Так что, как и в нашем случае, классы одинаковы, но предоставленные нами идентификаторы отличаются, что приводит к созданию двух разных экземпляров.