Como todos sabemos, tenemos beans como singleton de forma predeterminada en el contenedor Spring y si tenemos una aplicación web basada en el marco Spring, en ese caso, ¿realmente necesitamos implementar el patrón de diseño Singleton para contener datos globales en lugar de simplemente crear un bean a través de Spring? .
Por favor, tengan paciencia conmigo si no puedo explicar lo que realmente quería preguntar.
fuente
El alcance de singleton en Spring significa instancia única en un contexto de Spring.
El contenedor de Spring simplemente devuelve la misma instancia una y otra vez para las llamadas posteriores para obtener el bean.
Y Spring no se preocupa si la clase del bean está codificada como singleton o no, de hecho, si la clase está codificada como singleton cuyo constructor es privado, Spring usa BeanUtils.instantiateClass (javadoc aquí ) para configurar el constructor como accesible e invocar eso.
Alternativamente, podemos usar un atributo de método de fábrica en la definición de bean como este
fuente
Tomemos el ejemplo más simple: tienes una aplicación y solo usas el cargador de clases predeterminado. Tienes una clase que, por el motivo que sea, decides que no debe tener más de una instancia en la aplicación. (Piense en un escenario en el que varias personas trabajen en partes de la aplicación).
Si no está utilizando el marco Spring, el patrón Singleton asegura que no habrá más de una instancia de una clase en su aplicación. Esto se debe a que no puede crear instancias de la clase haciendo 'nuevo' porque el constructor es privado. La única forma de obtener una instancia de la clase es llamar a algún método estático de la clase (generalmente llamado 'getInstance') que siempre devuelve la misma instancia.
Decir que está utilizando el marco Spring en su aplicación, solo significa que, además de las formas habituales de obtener una instancia de la clase (métodos nuevos o estáticos que devuelven una instancia de la clase), también puede pedirle a Spring que lo obtenga una instancia de esa clase y Spring se asegurarán de que cada vez que le pida una instancia de esa clase, siempre devolverá la misma instancia, incluso si no escribió la clase usando el patrón Singleton. En otras palabras, incluso si la clase tiene un constructor público, si siempre le pide a Spring una instancia de esa clase, Spring solo llamará a ese constructor una vez durante la vida de su aplicación.
Normalmente, si está usando Spring, solo debe usar Spring para crear instancias, y puede tener un constructor público para la clase. Pero si su constructor no es privado, en realidad no está evitando que nadie cree nuevas instancias de la clase directamente, sin pasar por Spring.
Si realmente desea una única instancia de la clase, incluso si usa Spring en su aplicación y define la clase en Spring para que sea un singleton, la única forma de asegurarse de eso es también implementar la clase usando el patrón Singleton. Eso asegura que habrá una sola instancia, ya sea que las personas usen Spring para obtener una instancia o eviten Spring.
fuente
Encuentro " por contenedor por frijol" difícil de aprehender . Yo diría " un bean por id de bean en un contenedor ". Vamos a tener un ejemplo para entenderlo. Tenemos una clase de frijol Sample. He definido dos beans de esta clase en la definición de bean, como:
Entonces, cuando intento obtener el bean con id "id1", el contenedor de primavera creará un bean, lo almacenará en caché y devolverá el mismo bean donde se haya referido con id1. Si trato de obtenerlo con id7, se creará otro bean a partir de la clase Sample, el mismo se almacenará en caché y se devolverá cada vez que lo refiera con id7.
Esto es poco probable con el patrón Singleton. En el patrón Singlton, siempre se crea un objeto por cargador de clases. Sin embargo, en Spring, hacer que el alcance sea Singleton no restringe que el contenedor cree muchas instancias de esa clase. Simplemente restringe la creación de nuevos objetos para el mismo ID nuevamente, devolviendo el objeto creado anteriormente cuando se solicita un objeto para el mismo ID . Referencia
fuente
El alcance de Singleton en Spring significa que Spring instanciará este bean solo una vez. A diferencia del alcance del prototipo (nueva instancia cada vez), alcance de la solicitud (una vez por solicitud), alcance de la sesión (una vez por sesión HTTP).
El visor singleton técnicamente no tiene nada que ver con el patrón de diseño singleton. No tiene que implementar sus beans como singleton para que se coloquen en el alcance singleton.
fuente
Los frijoles Singleton en Spring y las clases basadas en el patrón de diseño Singleton son bastante diferentes.
El patrón Singleton garantiza que se creará una y solo una instancia de una clase en particular por cargador de clases, mientras que el alcance de un bean singleton de Spring se describe como 'por contenedor por bean'. El alcance de Singleton en Spring significa que Spring instanciará este bean solo una vez. Spring container simplemente devuelve la misma instancia una y otra vez para llamadas posteriores para obtener el bean.
fuente
Hay una diferencia fundamental entre los dos. En el caso del patrón de diseño Singleton, solo se creará una instancia de una clase por classLoader, mientras que ese no es el caso con Spring singleton, ya que en la última instancia se crea una instancia de bean compartido para el ID dado por contenedor IoC.
Por ejemplo, si tengo una clase con el nombre "SpringTest" y mi archivo XML se parece a esto: -
Entonces, ahora en la clase principal, si verifica la referencia de los dos anteriores, devolverá falso como de acuerdo con la documentación de Spring: -
Entonces, como en nuestro caso, las clases son las mismas, pero las identificaciones que hemos proporcionado son diferentes, por lo que se crean dos instancias diferentes.
fuente
"singleton" en spring usa la instancia de obtención de la fábrica de frijoles, luego la almacena en caché; qué patrón de diseño singleton es estrictamente, la instancia solo se puede recuperar del método get estático, y el objeto nunca se puede instanciar públicamente.
fuente
EX: "por contenedor por frijol".
JAVA SINGLETON:
fuente
El frijol spring singleton se describe como "por contenedor por frijol". El alcance Singleton en Spring significa que el mismo objeto en la misma ubicación de memoria se devolverá al mismo ID de bean. Si uno crea varios beans de diferentes ID de la misma clase, el contenedor devolverá diferentes objetos a diferentes ID. Esto es como una asignación de valor clave donde la clave es la identificación del frijol y el valor es el objeto del frijol en un contenedor de primavera. Donde, como patrón Singleton, se asegura que una sola instancia de una clase particular será creada por cargador de clases.
fuente
Todas las respuestas, al menos hasta ahora, se concentran en explicar la diferencia entre el patrón de diseño y el singleton Spring y no abordan su pregunta real: ¿Debería usarse un patrón de diseño Singleton o un bean singleton Spring? ¿Qué es mejor?
Antes de responder, permítame decirle que puede hacer ambas cosas. Puede implementar el bean como un patrón de diseño Singleton y usar Spring para inyectarlo en las clases cliente como un bean singleton de Spring.
Ahora, la respuesta a la pregunta es simple: ¡No use el patrón de diseño Singleton!
Use el bean singleton de Spring implementado como una clase con un constructor público.
¿Por qué? Porque el patrón de diseño Singleton se considera un anti-patrón. Sobre todo porque complica las pruebas. (Y si no usa Spring para inyectarlo, todas las clases que usan el singleton ahora están estrechamente vinculadas a él), y no puede reemplazarlo ni extenderlo. Se puede buscar en Google "Singleton anti-pattern" para obtener más información sobre esto, por ejemplo, Singleton anti-pattern
Usar Spring singleton es el camino a seguir (con un singleton bean implementado NO como un patrón de diseño Singleton, sino con un constructor público) para que el Spring singleton bean pueda probarse fácilmente y las clases que lo usan no estén estrechamente acopladas a él. , sino que Spring inyecta el singleton (como una interfaz) en todos los beans que lo necesitan, y el bean singleton se puede reemplazar en cualquier momento con otra implementación sin afectar a las clases cliente que lo usan.
fuente