#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'ами (отсюда оговорка "в рамках загрузчика классов") или другими грязными хаками.
Комментариев нет:
Отправить комментарий