proyecto patrones patron diseño conexion best java spring design-patterns singleton

patrones - Patrón de diseño de Java Singleton: preguntas



patrones de diseño java (11)

3: Por último, preguntó si es posible usar el objeto Singleton con clústeres con explicación y ¿hay alguna manera de que Spring no implemente el patrón de diseño Singleton cuando hacemos una llamada a Bean Factory para obtener los objetos?

La primera parte de esta pregunta es difícil de responder sin un contexto tecnológico. Si la plataforma del clúster incluye la capacidad de realizar llamadas a objetos remotos como si fueran objetos locales (por ejemplo, como es posible con los EJB que usan RMI o IIOP bajo el capó), entonces sí se puede hacer. Por ejemplo, los objetos singleton residentes de JVM podrían ser proxies para un objeto singleton de todo el clúster, que inicialmente se ubicó / cableó a través de JNDI o algo así. Pero los singletons en todo el clúster son un cuello de botella potencial porque cada llamada en uno de los proxys singleton da como resultado un RPC (costoso) a un solo objeto remoto.

La segunda parte de la pregunta es que Spring Bean Factories se puede configurar con diferentes ámbitos. El valor predeterminado es para singletons (con ámbito en el nivel de webapp), pero también pueden ser de sesión o solicitud de ámbito, o una aplicación puede definir su propio mecanismo de ámbito.

Recientemente tuve una entrevista y me preguntó sobre Singleton Design Patterns sobre cómo se implementan y le dije que usando variables estáticas y métodos estáticos podemos implementar Singleton Design Patterns.

Él parece estar medio satisfecho con la respuesta, pero quiero saber

  1. ¿Cuántas maneras diferentes podemos implementar Singleton Design Pattern en Java?
  2. ¿Cuál es el alcance de Singleton Object y cómo funciona realmente dentro de JVM? Sé que siempre tendríamos una instancia de Singleton Object, pero ¿cuál es el alcance real de ese objeto, está en JVM o si hay varias aplicaciones ejecutándose de acuerdo a su contexto dentro de la JVM, estaba realmente perplejo al respecto y no pudo dar una explicación satisfactoria?
  3. Por último, preguntó si es posible usar el objeto Singleton con clústeres con explicación y ¿hay alguna manera de que Spring no implemente el patrón de diseño Singleton cuando hacemos una llamada a Bean Factory para obtener los objetos?

¿Alguna información sería muy apreciada sobre Singleton y cuáles son las principales cosas a tener en cuenta al tratar con Singletons?

Gracias.


  1. Existe la forma estándar, que ya cubriste. Además, la mayoría de los esquemas de inyección de dependencia tienen alguna manera de marcar una clase como singleton; De esta manera, la clase se parece a cualquier otra, pero el framework se asegura de que cuando se inyectan instancias de esa clase, siempre sea la misma instancia.

  2. Ahí es donde se pone peludo. Por ejemplo, si la clase se inicializa dentro de un contexto de aplicación Tomcat, la duración de la instancia singleton está ligada a ese contexto. Pero puede ser difícil predecir dónde se inicializarán tus clases; así que es mejor no hacer suposiciones. Si desea asegurarse de que hay exactamente una instancia por contexto, debe vincularlo como un atributo de ServletContext. (O deje que un marco de inyección de dependencia se encargue de eso).

  3. -

  4. No estoy seguro de entender la pregunta, pero si está hablando de tener una instancia única compartida entre varios nodos del clúster, creo que EJB lo hace posible (a través de beans remotos), aunque nunca lo he intentado. No tengo idea de cómo lo hace Spring.


El siguiente código es de aquí

El punto clave es que debes Override el método de clone ... El ejemplo de Wikipedia también es útil.

public class SingletonObject { private SingletonObject() { // no code req''d } public static SingletonObject getSingletonObject() { if (ref == null) // it''s ok, we can call this constructor ref = new SingletonObject(); return ref; } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); // that''ll teach ''em } private static SingletonObject ref; }


Encuentro difícil de creer que tantas respuestas pasaron por alto la mejor práctica estándar para singletons, usando Enums, esto le dará un singleton cuyo alcance es el cargador de clases que es lo suficientemente bueno para la mayoría de los propósitos.

public enum Singleton { ONE_AND_ONLY_ONE ; ... members and other junk ... }

En cuanto a los solteros en niveles más altos, tal vez estoy siendo tonto, pero mi inclinación sería distribuir la JVM en sí (y restringir los cargadores de clase). Entonces la enumeración sería adecuada para el trabajo.


Hay algunas formas de implementar un patrón de Singleton en Java:

// private constructor, public static instance // usage: Blah.INSTANCE.someMethod(); public class Blah { public static final Blah INSTANCE = new Blah(); private Blah() { } // public methods } // private constructor, public instance method // usage: Woo.getInstance().someMethod(); public class Woo { private static final Woo INSTANCE = new Woo(); private Woo() { } public static Woo getInstance() { return INSTANCE; } // public methods } // Java5+ single element enumeration (preferred approach) // usage: Zing.INSTANCE.someMethod(); public enum Zing { INSTANCE; // public methods }

Teniendo en cuenta los ejemplos anteriores, tendrá una sola instancia por cargador de clases.

En cuanto al uso de un singleton en un clúster ... No estoy seguro de cuál es la definición de "usar" ... ¿implica el entrevistador que se crea una sola instancia en todo el clúster? No estoy seguro si eso tiene mucho sentido ...?

Por último, la definición de un objeto no único en primavera se realiza simplemente a través del atributo singleton = "false".


No estoy de acuerdo con @irreputable.

El alcance de un Singleton es su nodo en el árbol de Classloader. Su cargador de clases contenedor y cualquier cargador de clases hijo puede ver el Singleton.

Es importante entender este concepto de alcance, especialmente en los servidores de aplicaciones que tienen intrincadas jerarquías de Classloader.

Por ejemplo, si tiene una biblioteca en un archivo jar en el classpath del sistema de un servidor de aplicaciones, y esa biblioteca usa un Singleton, ese Singleton (probablemente) será el mismo para cada "aplicación" desplegada en el servidor de aplicaciones. . Eso puede o no ser algo bueno (depende de la biblioteca).

Los cargadores de clases son, en mi humilde opinión, uno de los conceptos más importantes en Java y JVM, y los Singleton juegan directamente con eso, así que creo que es importante que un programador de Java se "preocupe".


Singleton es un patrón creacional y, por lo tanto, rige la instanciación de objetos. La creación de singletons obligaría a renunciar voluntaria o involuntariamente al control sobre la creación del objeto y, en su lugar, confiar en alguna forma de obtener acceso a él.

Esto se puede lograr usando métodos estáticos o mediante inyección de dependencia o usando el patrón de fábrica. El medio es inmaterial. En el caso del enfoque del constructor protegido normal (), el consumidor necesariamente necesita usar el método estático para acceder al singleton. En el caso de DI, el consumidor voluntariamente cede el control sobre la instanciación de la clase y en su lugar se basa en un marco DI para inyectar la instancia en sí mismo.

Como señalan otros carteles, el cargador de clases en Java definiría el alcance del singleton. Los singletons en clusters generalmente no son "instancias únicas" sino una colección de instancias que muestran un comportamiento similar. Estos pueden ser componentes en SOA.


Singleton se implementa comúnmente al tener un objeto de instancia estático ( private SingletonType SingletonType.instance ) que se instancia de forma perezosa a través de un método SingletonType SingletonType.getInstance() estático. Hay muchas dificultades para usar singletons, tantos, de hecho, que muchos consideran singleton como un diseño anti patrón. Dadas las preguntas sobre Spring, el entrevistador probablemente buscaba una comprensión no solo de los singleton, sino también de sus dificultades, así como una solución alternativa para estas trampas conocida como inyección de dependencia. Puede encontrar el video en la página de Google Guice particularmente útil para comprender los peligros de los singleton y cómo DI aborda esto.


un campo estático puede tener múltiples ocurrencias en una JVM; al usar cargadores de clases de diferencias, la misma clase se puede cargar e inicializar varias veces, pero cada una vive aislada y JVM trata las clases cargadas como clases completamente diferentes.

No creo que a un programador de Java le importe, a menos que esté escribiendo algunos frameworks. "Uno por VM" es una buena respuesta. La gente a menudo habla de esa manera, mientras que en sentido estricto dicen "uno por cargador de clases".

¿Podemos tener un singleton por clúster? Bueno, eso es un juego de conceptos. No agradecería que un entrevistador lo diga de esa manera.


Singleton es un patrón de diseño creacional.

Intentos del patrón de diseño Singleton:

  • Asegúrese de que una clase tenga solo una instancia y proporcione un punto de acceso global a ella.
  • "Inicialización just-in-time" encapsulada o "inicialización en el primer uso".

Estoy mostrando tres tipos de implementación aquí.

  1. Inicialización justo a tiempo (Asigna memoria durante la primera ejecución, incluso si no la usa)

    class Foo{ // Initialized in first run private static Foo INSTANCE = new Foo(); /** * Private constructor prevents instantiation from outside */ private Foo() {} public static Foo getInstance(){ return INSTANCE; } }

  2. Inicialización en el primer uso (o inicialización lenta)

    class Bar{ private static Bar instance; /** * Private constructor prevents instantiation from outside */ private Bar() {} public static Bar getInstance(){ if (instance == null){ // initialized in first call of getInstance() instance = new Bar(); } return instance; } }

  3. Este es otro estilo de inicialización Lazy, pero la ventaja es que esta solución es segura para subprocesos sin requerir construcciones de lenguaje especiales (es decir, volátil o sincronizada). Lea más en SourceMaking.com

    class Blaa{ /** * Private constructor prevents instantiation from outside */ private Blaa() {} /** * BlaaHolder is loaded on the first execution of Blaa.getInstance() * or the first access to SingletonHolder.INSTANCE, not before. */ private static class BlaaHolder{ public static Blaa INSTANCE = new Blaa(); } public static Blaa getInstance(){ return BlaaHolder.INSTANCE; } }


Consulta 1:

Diferentes formas de crear Singleton

  1. Normal Singleton : inicialización estática
  2. ENUM
  3. Lazy Singleton : doble bloqueo Singleton &: initialization-on-demand_holder_idiom singleton

Echa un vistazo al siguiente código:

public final class Singleton{ private static final Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } public enum EnumSingleton { INSTANCE; } public static void main(String args[]){ System.out.println("Singleton:"+Singleton.getInstance()); System.out.println("Enum.."+EnumSingleton.INSTANCE); System.out.println("Lazy.."+LazySingleton.getInstance()); } } final class LazySingleton { private LazySingleton() {} public static LazySingleton getInstance() { return LazyHolder.INSTANCE; } private static class LazyHolder { private static final LazySingleton INSTANCE = new LazySingleton(); } }

Preguntas relacionadas con SE:

¿Cuál es una forma eficiente de implementar un patrón singleton en Java?

Consulta 2:

Se crea una instancia de Singleton por ClassLoader . Si desea evitar la creación de un objeto Singleton durante la Serializaiton , anule el siguiente método y devuelva la misma instancia.

private Object readResolve() { return instance; }

Consulta 3:

Para lograr un Singleton nivel de clúster entre varios servidores, almacene este objeto Singleton en cachés distribuidos como Terracotta , Coherence , etc.