tipos scopedproxymode bean annotation java multithreading spring concurrency singleton

java - scopedproxymode - ¿Es este diseño de hilo singleton Spring seguro?



spring singleton annotation (6)

¿Es correcto decir que la clase DocumentService es inmutable ya que no es posible mutar ninguno de sus dos campos (que son beans de primavera que pueden ser inicializados solo una vez por el contenedor)?

De acuerdo con la definición de inmutabilidad , y formalmente hablando, esta clase NO es inmutable .

Un objeto es inmutable si no es posible cambiar el estado del objeto, y el estado de documentGenerationService y documentPublishService es parte del estado de la clase DocumentService .

Y, como resultado, si la clase tiene siempre el mismo estado, se comporta siempre de la misma manera . En otras palabras, no hay forma de cambiar el comportamiento de un objeto inmutable porque el comportamiento de un objeto depende solo de su estado, y en un objeto inmutable, este estado nunca cambia (los ejemplos de objetos inmutables son cadenas y enteros).

Tenga en cuenta que en la definición de inmutabilidad encontramos una excepción en la que " un objeto se considera inmutable incluso si algunos [...] atributos cambian, pero el estado del objeto [y, por lo tanto, el comportamiento] parece no cambiar [...] ", pero en este caso (con la información provista) un cambio en el estado de las referencias definitivamente podría cambiar el comportamiento de la clase (ya que no tenemos ningún control sobre su propio estado interno).

Hay una strategy para hacer una clase inmutable. Ya sigues algunas de sus pautas, pero en caso de que desees hacerlo inmutable (creo que no es el caso) necesitarás otras como hacer una "copia defensiva" de los argumentos que recibes en el constructor y evitar las subclases anuladas. metodos

Este link también es interesante.

Sin embargo, no debe hacer que los frijoles Spring sean inmutables, ya que no es la manera de usar el modelo de programación que Spring ofrece. Entonces, en este caso, es "bueno" que la clase no sea inmutable.

En cualquier caso, ¿el bean DocumentService, tal como se define anteriormente, puede considerarse seguro para subprocesos?

Como se declara aquí, esta clase es segura para subprocesos . Muchos hilos pueden acceder de forma segura a esta clase sin que surja ninguna condición de carrera. No podemos decir lo mismo sobre los campos que contiene, pero esta clase es segura para subprocesos. Esto funciona de la misma manera que la "lista segura de subprocesos": puede contener objetos "no seguros para subprocesos", pero sigue siendo una "lista segura de subprocesos".

¿Y si se sigue este diseño, la aplicación en su conjunto también es segura para subprocesos?

Si todas las clases de su sistema son seguras para subprocesos (es decir, no aparece una sola condición de carrera en ninguna parte), informalmente podría decir que la aplicación es segura para subprocesos.

Considere la siguiente clase de servicio de primavera. El alcance del resorte definido es Singleton. Los dos beans de servicio cableados automáticamente como campos en la clase a continuación tienen una estructura similar; también están compuestos de campos que son cualquiera de los siguientes

  • Frijoles de primavera ellos mismos
  • clases sin estado
  • clases inmutables

y así. Este patrón se utiliza en general en el diseño de la aplicación.

@Service public class DocumentService { private final DocumentGenerationService documentGenerationService; private final DocumentPublishService documentPublishService; @Autowired public DocumentService (DocumentGenerationService documentGenerationService, DocumentPublishService documentPublishService) { this.documentGenerationService = documentGenerationService; this.documentPublishService = documentPublishService; } ... methods follow

¿Es correcto decir que la clase DocumentService es inmutable ya que no es posible mutar ninguno de sus dos campos (que son beans de primavera que pueden ser inicializados solo una vez por el contenedor)?

En cualquier caso, ¿el bean DocumentService, tal como se define anteriormente, puede considerarse seguro para subprocesos? ¿Y si se sigue este diseño, la aplicación en su conjunto también es segura para subprocesos?


El código de ejemplo que se muestra en tu pregunta es definitivamente seguro para subprocesos.

Sin embargo, el código debe considerarse en el contexto de toda la aplicación. Por ejemplo, el código anterior no ofrece ninguna garantía sobre la seguridad de los objetos a los que hace referencia los atributos documentGenerationService y documentPublishService . Si no están sincronizados adecuadamente, es posible que el código que los utiliza (incluidos otros métodos de esta clase) no sea seguro para subprocesos.


La primavera no garantiza la seguridad del hilo, cuando dice que los frijoles son singleton. Si creas bean de alcance singleton en spring, simplemente significa que se crea una única instancia de objeto por contenedor Spring IoC. Pero aún así, esa clase de bean de ámbito Singleton puede no ser segura para subprocesos en sí misma, por lo que es responsabilidad del programador hacer que el subproceso del código sea seguro.


La primavera no garantiza la seguridad del hilo. Esa es tu responsabilidad.

Todas las variables de miembros privados son compartidas. Pueden ser finales, pero eso solo significa que las referencias no se pueden cambiar. Cualquier estado mutable debe estar sincronizado. Si son realmente inmutables, entonces creo que estás en tierra firme.

Estoy de acuerdo con el comentario sobre las dependencias de conexión automática. Los dejaría bajo el control de Spring si es posible.


Puede poner la anotación @Autowired encima de los servicios en lugar de usarlos en el constructor. Es un bean administrado por Spring, lo que significa que es un singleton. Es seguro para subprocesos, pero eso depende de la implementación.

@Service public class DocumentService { @Autowired private DocumentGenerationService documentGenerationService; @Autowired private DocumentPublishService documentPublishService; ... methods follow


Tu código parece seguro para subprocesos. La primavera no garantiza la seguridad del hilo, cuando dice que los frijoles son singleton. Si creas bean de alcance singleton en spring, simplemente significa que se crea una única instancia de objeto por contenedor Spring IoC. Pero aún así, esa clase de bean de ámbito Singleton puede no ser segura para subprocesos en sí misma, por lo que es responsabilidad del programador hacer que el subproceso del código sea seguro.

En su código, documentGenerationService por ejemplo es final. Eso garantiza que las referencias no pueden cambiar, y también a partir del nuevo modelo de memoria Java, se garantiza la creación de instancias. Pero @duffymo dijo, los objetos a los que se hace referencia también deben ser inmutables.

Descansa todo es bueno :)