Подтвердить что ты не робот

Является ли spring областью действия по умолчанию singleton или нет?

Не могли бы вы объяснить, почему Spring создает два объекта для конфигурации beans, показанных ниже, поскольку по умолчанию Spring по умолчанию используется Singleton?

Конфигурация Spring находится здесь:

<bean id="customer" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="100"></property>
    <property name="custName" value="rajasekhar"> </property>
</bean>
<bean id="customer2" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="200"></property> 
    <property name="custName" value="siva"></property> 
</bean>
4b9b3361

Ответ 1

Spring Значение по умолчанию - Singleton. Это просто, что ваша идея о том, что означает синглтон, не соответствует тому, как Spring определяет одиночные числа.

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

Вот как документация Spring определяет одноэлементную область:

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

Singleton scope означает, что один и тот же идентификатор получает тот же самый bean, вот и все. Тестирование, что никакие два идентификатора не ссылались на один и тот же класс, помешало бы использовать карты как beans, и было бы сложно проксировать вещи с помощью BeanFactories. Для Spring для полиции это потребует большой работы для небольшой выгоды, вместо этого он доверяет пользователям знать, что они делают.

Способ определения двух имен для одного и того же bean заключается в использовании alias:

В самом определении bean вы можете указать более одного имени для bean, используя комбинацию до одного имени, указанного атрибутом id, и любое количество других имен в атрибуте name. Эти имена могут быть эквивалентными псевдонимами для одного и того же bean и полезны для некоторых ситуаций, например, позволяя каждому компоненту приложения ссылаться на общую зависимость с помощью имени bean, которое является специфическим для этого самого компонента.

Указание всех псевдонимов, где фактически определено bean, не всегда адекватно. Иногда желательно ввести псевдоним для bean, который определен в другом месте. Обычно это происходит в больших системах, где конфигурация разделяется между каждой подсистемой, причем каждая подсистема имеет свой собственный набор определений объектов. В метаданных конфигурации на основе XML вы можете использовать этот элемент для выполнения этого.

Итак, если вы добавите имя в конфигурацию bean:

<bean id="customer" name="customer2" 
    class="jp.ne.goo.beans.Customer">
</bean>

или создать псевдоним для bean, определенного в другом месте:

<alias name="customer" alias="customer2"/>

тогда "клиент" и "клиент2" будут ссылаться на тот же экземпляр bean.

Ответ 2

Spring default scope - singleton, и он создаст один объект для всех экземпляров, если вы явно не укажете область действия прототипа. Вы не разместили конфигурацию spring. Пожалуйста, опубликуйте его, это даст лучшую идею.

Ответ 3

Вы смешиваете две разные концепции.

Слово singleton в spring используется для области bean, что означает, что bean будет создаваться только один раз для всего приложения.

Синглтонное обычное значение относится к шаблону GOF. Это объектно-ориентированный шаблон, гарантирующий существование только одного экземпляра класса (по крайней мере, в рамках классаLoader).

Ответ 4

Вы объявляете два beans того же класса. Это не то же самое.

@Component("springTestClass")
public class SpringTestClass{
     private int randomNumber = 0;
     public SpringTestClass(){
       randomNumber = new Random().nextInt(2000);
     }

     public int getRandomNumber(){
       return this.randomNumber;
     }

}

И попробуйте получить доступ к этому bean в двух местах, номер будет таким же. Но вы сделали два отдельных beans.

Если вы хотите проверить, работает ли это, выполните следующие действия:

public class Main{
   public static void main(String[] args){
     ApplicationContext ctx = ....;
     SpringTestClass testObject1 = (SpringTestClass)ctx.getBean("springTestClass");
     SpringTestClass testObject2 = (SpringTestClass)ctx.getBean("springTestClass");

    System.out.println(testObject1.getRandomNumber() == testObject2.getRandomNumber());
   }
}

Этот код должен возвращать true, если это тот же самый экземпляр; Но в SpringTestClass вы можете добавить аннотацию @Scope ("prototype"). Выход будет ложным

Ответ 5

Как и многие другие, два кода beans должны быть созданы из кода, который вы опубликовали. Синглтоны определяются следующим образом (из документации Spring: Singleton Scope)

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

Чтобы добавить ясность в это, значение, стоящее за "общим экземпляром", объясняется в абзаце, который следует за приведенным выше:

все последующие запросы и ссылки для имени с именем bean возвращают кешированный объект

Когда создается одноэлемент bean, создается только один объект bean и кэшируется. Это относится только к bean, а не к любому классу, который может быть bean. Например,

<bean id="myBean" class="myPackage.myClass" />

<bean id="myOtherBean1 class="myPackage.myOtherClass1">
    <property name="beanReference1" ref="myBean" />
</bean>
<bean id="myOtherBean2 class="myPackage.myOtherClass2">
    <property name="beanReference2" ref="myBean" />
</bean>

В этой конфигурации, "myOtherBean1" и "myOtherBean2" имеют ссылки на один и тот же "myBean" bean, следовательно, тот же самый экземпляр "myPackage.myClass" . Если вы изменили код, чтобы добавить второй "myPackage.myClass" bean, он будет отличаться от "myBean" .

Чтобы полностью понять это, также обратитесь к другой области Spring: прототип. Из документации Spring для Масштаб прототипа:

Неэлементный, прототип области развертывания bean приводит к созданию нового экземпляра bean каждый раз, когда выполняется запрос для этого конкретного bean.

Это означает, что если бы мы использовали тот же самый Spring XML, как указано выше, "myOtherBean1" и "myOtherBean2" получат свои собственные отдельные копии "myBean" , которые по-прежнему являются только экземпляром "myPackage.myClass" ,.

Ответ 6

В следующем примере показан аннотированный метод @Bean, вызываемый дважды:

@Configuration
public class AppConfig {

    @Bean
    public ClientService clientService1() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientService clientService2() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientDao clientDao() {
        return new ClientDaoImpl();
    }

}

clientDao() вызывается один раз в clientService1() и один раз в clientService2(). Поскольку этот метод создает новый экземпляр ClientDaoImpl и возвращает его, вы обычно ожидаете иметь 2 экземпляра (по одному для каждой службы). Это определенно было бы проблематично: в Spring экземпляры bean-компонентов по умолчанию имеют одноэлементную область видимости. В этом и заключается магия: все классы @Configuration подклассируются во время запуска с помощью CGLIB. В подклассе дочерний метод сначала проверяет контейнер на наличие кэшированных (ограниченных) bean-компонентов, а затем вызывает родительский метод и создает новый экземпляр. Обратите внимание, что начиная с Spring 3.2 больше нет необходимости добавлять CGLIB в ваш путь к классам, потому что классы CGLIB были переупакованы в org.springframework.cglib и включены непосредственно в JAR файл Spring-Core.

Ответ 7

В SPring Singleton ссылается на Один компонент на контейнер Spring, где, как в Java, Singleton ссылается на один объект на загрузчик классов.

Так что Spring Singleton - это не то же самое, что Java Singleton. Не путайся между этими двумя.

Ответ 8

Spring Singleton Bean Не работает как Java Singleton.

Если мы напишем

ApplicationContext ctx = new ClassPathXmlApplicationContext("MyConfig.xml");
        Customer obj1= (Customer) ctx.getBean("customer");
        Customer obj2 = (Customer) ctx.getBean("customer2");
        System.out.println(obj1 == obj2);
        System.out.println(obj1+ "::" + obj2);

Если мы увидим вывод, он вернет 2 разных экземпляра. Согласно Spring Docs Bean - это одноэлементный компонент, которым будет управляться только один общий экземпляр, и все компоненты будут запрашивать с идентификатором или идентификатором, совпадающим с определением компонента. Здесь доступно 2 разных идентификатора.

Spring-контейнер как управляющая пара ключ-значение, Key-идентификатор/имя и значение - bean-компонент.