Principios básicos de las dependencias circulares
El proceso de obtención de una instancia de Bean del contenedor Spring IOC: a partir del método context.getBean()
¿Por qué debería eliminarse el caché de tercer nivel?
Busque en el caché de tercer nivel, realice AOp para generar un objeto proxy después de encontrarlo y luego coloque el objeto proxy en el caché de segundo nivel. El caché de tercer nivel definitivamente encontrará el objeto, pero no necesariamente realizará el aop. Solo cuando el caché de segundo nivel no puede encontrar el objeto, se activará el aop (ejecutará la interfaz funcional a través de la expresión lambda y ejecutará el aop), generará un objeto proxy y lo colocará en el caché de segundo nivel, y luego lo colocará. en el caché de segundo nivel Luego, es necesario eliminar el caché de tercer nivel correspondiente (para garantizar que aop solo se ejecute una vez).
¿Por qué grupo singleton: concurrentHashmap, L2 hashmap, L3 hashmap?
El proceso AOP de la caché L3 requiere bloqueo para garantizar la atomicidad de la operación.
Porque la caché L3 es la primera caché utilizada.
Debido a que la interfaz de función del caché de tercer nivel ha agregado bloqueos internamente para garantizar la atomicidad, no es necesario usar concurenthashmap
Pregunta: ¿Cuál es el significado de agregar bloqueos de sincronización en el código fuente?
Antecedentes:
El objeto aService en el caché de segundo nivel es generado por la expresión lambda en el caché de tercer nivel
Están emparejados. el caché de segundo nivel Si hay un objeto proxy en el caché de primer nivel, entonces la expresión lambda no debería existir en el caché de tercer nivel
O si hay una expresión lambda, entonces el proxy; el objeto no debe existir en el caché de segundo nivel
Solución:
Entre ellos:
Es la operación de almacenar la información del objeto original en el caché de tercer nivel. caché de nivel El método de almacenamiento es una expresión lambda:
getEarlyBeanReference (beanName, mbd, bean) es el resultado de ejecutar getEarlyBeanReference. getEarlyBeanReference juzgará si es necesario promover AOP. se generará y almacenará en la caché de segundo nivel.
Entre ellos:
1. Cuando A se inicializa en doCreateBean(), dado que aún no se ha creado, no se puede encontrar en el caché de primer nivel en este momento. , es solo un producto semiacabado (objeto expuesto tempranamente), ingrese al caché de tercer nivel singletonFactories
2. A descubre que necesita el objeto de B, pero no puede encontrar B en el tercer nivel; caché de nivel. Entonces se crea el objeto original de B y la expresión lambda que contiene información del objeto B (beanName, bd, objeto original) se coloca en singletonFactories;
3.B se da cuenta de que necesita el objeto A, en el primer nivel No se encontró en el caché singletonObjects y se enteró de que se estaba creando el objeto A, lo que confirmó la dependencia circular. Luego buscó el objeto A en el caché de segundo nivel earlySingletonObjects. para el objeto A en el caché de tercer nivel singletonFactories (puede encontrarlo) y luego obtener el objeto proxy u objeto original A (a A no se le asigna un valor en el atributo) en la expresión lambda de ejecución del caché de tercer nivel . Coloque A en earlySingletonObjects en el caché de segundo nivel y elimine la expresión correspondiente a beanName del caché de tercer nivel.
De manera similar, cuando se agrega un objeto al caché de tercer nivel, también se agregará; eliminados de la caché de segundo nivel. Registros con el mismo nombre de bean, por lo que la operación de dos pasos entre las cachés L2 y L3 es atómica.
4.A se inyecta en el objeto B;
5.B completa el llenado de atributos, ejecuta el método de inicialización y se coloca en el caché de primer nivel (en este momento, B es un objeto completo);
6.A obtiene el objeto B e inyecta B en A
7. A completa el llenado de atributos, la inicialización y se coloca en el caché de primer nivel
Nota: Al comienzo de la creación del objeto, el estado de creación del objeto se registrará usando Set:
singletonsCurrentlyInCreation: si se está creando, esto se puede usar para determinar si hay una dependencia circular. ha ocurrido.
El papel de la anotación @Lazy:
inicializeBean
Spring resuelve el problema de la dependencia circular: vídeo en el sitio B
Spring circular Preguntas "comunes" de la entrevista sobre dependencia