2010-07-09 9 views
5

La pregunta es un poco larga ya que es conceptual. Espero que no sea una mala lectura :)Controlador (Bean administrado por Spring Bean) Pregunta de Alcance: Singleton, Solicitud o Sesión?

Estoy trabajando en una aplicación web Spring MVC/Tiles crítica para el rendimiento (10,000 usuarios de carga típica). Cargamos una pantalla de actualización de empleados, donde cargamos una pantalla de detalles del empleado (vinculada a un objeto comercial del empleado) para actualizaciones a través de un MultiActionController. Hay varias pestañas en esta pantalla, pero solo la pestaña 1 tiene los datos actualizados. El resto de las pestañas son de solo lectura, básicamente como referencia.

No hace falta decir que hemos decidido cargar estas pestañas de solo lectura de manera perezosa, es decir, cuando cada pestaña está activada, activamos una llamada ajax (una vez) para recuperar los datos del servidor. No cargamos todo a través del método de carga de la vista de actualización. Recuerde: esto es solo una vez, datos de solo lectura.

Ahora, estoy en un dilema. He creado otro controlador multiacción, llamado "AjaxController" para manejar estas llamadas ajax. Ahora, mis preguntas:

  1. ¿Cuál debe ser el mejor ámbito para este controlador?

Pensamientos: Si lo solicito con un alcance, entonces 10,000 usuarios juntos pueden crear 10,000 instancias de este bean: problema de memoria allí. Si hago que sea una sesión con ámbito, se creará una por sesión de usuario. Eso significa que cuando 10,000 usuarios inicien sesión en la aplicación, independientemente de si tocan los métodos de AjaxController, cada uno tendrá un bean en posesión.

  1. Entonces, ¿es el mejor alcance para este controlador?

Pensamientos: Se creará un bean singleton cuando se arranque la primavera, y esta misma instancia se proporcionará en todas partes. Suena bien.

  1. ¿Deberían los métodos del controlador (como fetchTab7DataInJsonFormat) ser estáticos y estar adjuntos a la clase?

Pensamientos: En este caso, ¿pueden los métodos estáticos entrar en conflicto de forma semántica con el alcance? Por ejemplo: does scope = "session"/"request" + static methods tiene sentido? Lo pregunto porque aunque cada sesión de usuario tiene su propio bean AjaxController, los métodos del manejador están realmente conectados a la clase, y no a las instancias. Además, ¿tiene sentido scope = "singleton" + métodos de controlador estático?

  1. ¿Puedo aplicar el patrón de diseño Singleton en AjaxController manualmente?

Pensamientos: ¿Qué pasa si controlo la creación: haga el singleton de GoF básicamente. Entonces, ¿qué puede hacer la especificación del alcance? La sesión/solicitud de alcance seguramente no puede crear múltiples instancias, ¿verdad?

  1. Si, por cualquier mecanismo (especificación de bean/patrón de diseño/métodos estáticos), consigo tener una sola instancia de AjaxController: ¿Es necesario sincronizar estos métodos STATIC? Creo que no, porque incluso si los métodos de los manejadores STATIC pueden hablar con servicios (que hablan con DB/WS/MQ etc.) que toman tiempo, creo que cada hilo de solicitud que ingresa a los métodos estáticos será devuelto por su identificación del hilo ¿correcto? No es como que el usuario 1 ingresa el método estático, y luego el usuario 2 ingresa el método estático antes de que se haya devuelto user1, y luego ambos obtienen algunos datos confusos. Esto es probablemente una tontería, pero quiero estar seguro.

I'm confused. Básicamente, quiero exactamente una sola instancia del frijol controlador atendiendo todas las solicitudes para todos los clientes.

Nota crítica: El bean AjaxController no se INYECTA en ningún otro lado, existe aislado. Sus métodos son golpeados a través de llamadas ajax.

Respuesta

3

Si estuviera haciendo esto, definitivamente haría el singleton LazyLoadController sin tener métodos estáticos y sin ningún estado en él.

Además, definitivamente no debe crear instancias de singleton manualmente, es mejor usar el mecanismo común de Spring y dejar que el framework controle todo.

La idea general es evitar el uso de métodos estáticos y/o datos persistentes en los controladores. El mecanismo correcto sería utilizar algún bean de servicio para generar datos para la solicitud, por lo que el controlador actúa como despachador de parámetros de solicitud para extraer los datos a la vista. No debe permitirse ningún estado mutable o cosas inseguras en el controlador. Si algunos componentes son específicos del usuario, el sistema AOP de Spring proporciona la inyección de los componentes según la sesión/solicitud.

Eso es una buena práctica para hacer algo así. Hay algo que aclarar para dar una respuesta más específica para su caso. ¿Entendí bien que el caso típico de uso será que AjaxController pasará algunas de las solicitudes a LazyLoadController para obtener datos de pestañas? Proporcione detalles al respecto en su comentario o en su pregunta, de modo que pueda actualizar mi respuesta.

Lo que está mal con tener métodos estáticos en el controlador es que tiene que administrar la seguridad concurrente usted mismo, que no solo es propenso a errores, sino que también reducirá el rendimiento general. Spring ejecuta cada solicitud en su propio hilo, por lo que si dos llamadas simultáneas necesitan utilizar algún método estático y hay recursos compartidos (por lo que debe usar la instrucción de sincronización o bloqueos), uno de los hilos tendrá que esperar a que otro finalice el trabajo. en bloque protegido Por otro lado, si usa servicios sin estado y evita tener datos que pueden compartirse para llamadas múltiples, obtendrá un mayor rendimiento y no tendrá que lidiar con el acceso a datos simultáneos.

+0

Gran error de mi parte. LazyLoadController IS AjaxController. Pensé en un nombre mientras comenzaba a escribir preguntas, y luego volví a usar otro nombre durante las preguntas. Mis disculpas, he editado la publicación. Sí, tiene el uso correcto. De hecho, tengo una capa de servicio que hace precisamente eso, y este AjaxController simplemente actúa como un despachador de solicitudes y un controlador de respuestas. Algunas de mis dudas permanecen con respecto a los escenarios de conflicto. Actualmente mi AjaxController es singleton y tiene métodos estáticos para procesar solicitudes e interactuar con la capa de servicio. ¿Algo está mal esta configuración? – SpringConfused

+0

Ya veo. Actualicé mi respuesta con una explicación de por qué los métodos estáticos son incorrectos. –

Cuestiones relacionadas