¿El controlador de Spring es singleton o múltiples instancias? Cómo garantizar la seguridad de la concurrencia

Autor | riemann_

Fuente | blog.csdn.net/riemann_/article/details/97698560


responder

El controlador es singleton por defecto, no utilice variables miembro no estáticas, de lo contrario se producirá confusión en la lógica de datos. No es seguro para subprocesos debido al singleton.

Verifiquemos brevemente lo siguiente:

package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author riemann
 * @date 2019/07/29 22:56
 */
@Controller
public class ScopeTestController {

    private int num = 0;

    @RequestMapping("/testScope")
    public void testScope() {
        System.out.println(++num);
    }

    @RequestMapping("/testScope2")
    public void testScope2() {
        System.out.println(++num);
    }

}

Primero visitamos  http://localhost:8080/testScopey la respuesta fue sí 1; luego visitamos nuevamente  http://localhost:8080/testScope2y la respuesta fue sí  2.

Obtenga diferentes valores, que no son seguros para subprocesos.

A continuación, controlleragreguemos más casos @Scope("prototype")

package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author riemann
 * @date 2019/07/29 22:56
 */
@Controller
@Scope("prototype")
public class ScopeTestController {

    private int num = 0;

    @RequestMapping("/testScope")
    public void testScope() {
        System.out.println(++num);
    }

    @RequestMapping("/testScope2")
    public void testScope2() {
        System.out.println(++num);
    }

}

Todavía visitamos primero  http://localhost:8080/testScope, y la respuesta fue sí 1; luego visitamos nuevamente  http://localhost:8080/testScope2, y la respuesta fue tranquila  1.

Creo que no es difícil para todos encontrar:

Los singleton no son seguros y darán lugar al uso repetido de atributos.

"Recomiende un tutorial básico de SpringBoot escrito por DD: http://blog.didispace.com/spring-boot-learning-2x/

solución

1. No defina variables miembro en el controlador. 2. En caso de que sea necesario definir una variable miembro no estática, establézcala en modo multi-case a través de la anotación @Scope ("prototipo"). 3. Use variables ThreadLocal en Controller

Suplemento

El alcance del frijol de primavera tiene los siguientes 5:

  • Singleton: modo Singleton, cuando Spring crea un contenedor applicationContext, Spring querrá inicializar todas las instancias del alcance, más lazy-init para evitar el preprocesamiento;

  • Prototipo: modo prototipo, cada vez que se obtenga el bean a través de getBean, se generará una nueva instancia y Spring ya no lo administrará después de la creación;

    (Lo siguiente solo se usa en el proyecto web)

  • solicitud: Todo aquel que se dedique a la web debe conocer el dominio de la solicitud, es decir, se genera una nueva instancia para cada solicitud, la diferencia con el prototipo es que después de la creación, Spring sigue monitoreando;

  • sesión: cada sesión, igual que la anterior;

  • Sesión global: dominio web global, similar a la aplicación en servlet.

No hay manera, pero la técnica se puede lograr; si no hay manera, termina con la técnica.

Bienvenidos a todos a seguir la cuenta pública de Java Way

Buen artículo, estoy leyendo ❤️

Supongo que te gusta

Origin blog.csdn.net/hollis_chuang/article/details/108505326
Recomendado
Clasificación