Comprensión profunda de cómo Spring resuelve las dependencias circulares
Esto se puede simplificar en los siguientes 5 pasos.
1. Construir BeanDefinition
2. Creación de instancias
3. Asignación de atributos Rellenar
4. Inicialización (BeanPostprocessor -> Aware, init )
5. Destrucción
Un ciclo utilizado para guardar, inicializar y completar dependencias. )
5, Destrucción
Un bucle utilizado para guardar la creación de instancias, inicialización y finalización de objetos bean.
Se utiliza para guardar el objeto cuya instanciación se completa pero la inicialización no se completa (este objeto no es necesariamente el objeto original, pero también puede ser un objeto proxy generado a través de AOP).
ObjectFactory se utiliza para contener la fábrica de objetos, que proporciona una clase interna anónima para crear objetos en el caché de segundo nivel.
El ObjectFactory mencionado en el caché de tercer nivel es ()-> getEarlyBeanReference(beanName,mbd,bean), donde bean es el objeto original.
El método getEarlyBeanReference se define en la interfaz SmartInstantiationAwareBeanPostProcessor y AbstractAutoProxyCreator (creador del proxy Spring AOP) implementa este método.
Carga en el orden de caché de primer nivel, caché de segundo nivel y caché de tercer nivel respectivamente. Si hay una dependencia circular (por ejemplo, beanName:B depende de beanName:A) y existe una referencia a beanName:A en la caché de tercer nivel, el objeto expuesto anteriormente correspondiente a beanName:A debe obtenerse del tercer nivel. -caché de nivel (puede ser el objeto original o el objeto proxy) y colóquelo en el caché de segundo nivel. Por ejemplo, si beanName:A depende de otro beanName:C, se recuperará directamente de la caché de segundo nivel.
Agregar directamente al caché de primer nivel
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(beanName:A, enableEarlyReference:false)
@ Transactional utiliza el creador automático de proxy AbstractAutoProxyCreator, que implementa el método getEarlyBeanReference() para proporcionar un buen soporte para dependencias circulares.
La creación de proxy de @Async utiliza una implementación de posprocesador independiente, AsyncAnnotationBeanPostProcessor, que crea el objeto proxy en una única ubicación (postProcessAfterInitialization()), por lo que si se utiliza en un bucle.
2. Si no hay dependencia circular, no se utilizará el caché de tercer nivel (singletonFactories), pero el objeto se creará de acuerdo con el proceso del ciclo de vida de Spring Bean y, finalmente, el bean se creará. colocado directamente en el caché de primer nivel (singletonObjects).
3. Debemos tener un caché de tercer nivel. ¿No puede el caché de segundo nivel resolver dependencias circulares? No, se utiliza principalmente para generar proxies.
Debido a que el caché de tercer nivel contiene una clase interna anónima (ObjectFactory), esta clase genera objetos específicos, que pueden generar servidores proxy u objetos de instancia ordinarios.
La razón principal para utilizar el caché de nivel 3 es garantizar que el objeto se utilizará pase lo que pase. Supongamos que solo hay un caché de segundo nivel y que los objetos Bean ordinarios se muestran en el caché de segundo nivel. Cuando BeanPostProcessor genera un objeto proxy, sobrescribe los objetos Bean ordinarios en el caché de segundo nivel y no puede garantizar la coherencia. de objetos Bean en un entorno multiproceso.