Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Разница между singleton в Java и в Spring

#java #spring


Наткнулась на такие строки про область видимости Singleton в Spring:


  Note that there is a subtle difference between the instance obtained
  using the Java Singleton pattern and Spring Singleton. Spring
  Singleton is a singleton per context or container, whereas the Java
  Singleton is per process and per class loader.


Мой перевод:


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


И, во-первых, хотелось бы удостовериться, что мой перевод правильный. А во-вторых,
хотелось бы глубже понять разницу между singleton в Java и в Spring...
    


Ответы

Ответ 1



Перевод верный. Spring Singleton уникален в рамках контекста или контейнера Это значит, что каждый раз, запрашивая singleton-бин из одного и того же контекста, вы будете получать один и тот же объект: ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context.xml"); MySingleton s1 = ctx.getBean("mySingleton", MySingleton.class); MySingleton s2 = ctx.getBean("mySingleton", MySingleton.class); // s1 == s2 Но если синглтон будет получен из другого контекста или будет создан НЕ Spring'ом (через new или какой-нибудь другой контейнер), вы получите другой объект. ApplicationContext ctx1 = new ClassPathXmlApplicationContext("/application-context.xml"); ApplicationContext ctx2 = new ClassPathXmlApplicationContext("/application-context.xml"); MySingleton s1 = ctx1.getBean("mySingleton", MySingleton.class); MySingleton s2 = ctx2.getBean("mySingleton", MySingleton.class); MySingleton s3 = new MySingleton(); // s1 != s2 // s2 != s3 // s1 != s3 Java Singleton уникален в рамках процесса или загрузчика классов Это значит, что в рамках одного процесса JVM вы не сможете создать два разных экземпляра класса синглтона*. В этом случае сам класс-синглтон должен конроллировать процесс создания собственных экземпляров (в отличие от предыдущего случая, где этот процесс контроллируется контейнером Spring'а). Обычно этого добиваются, делая конструктор private и разрешая получать экземпляры класса только через статический метод этого класса, который всегда отдаёт один и тот же объект. * Это можно попытаться обойти при помощи Reflections API, загрузки одного и того же класса несколькими classloader'ами (отсюда оговорка "в рамках загрузчика классов") или другими грязными хаками.

Комментариев нет:

Отправить комментарий