Red de conocimiento informático - Problemas con los teléfonos móviles - Error de dependencia circular de Spirng: ¿Hay una referencia circular sin resolver?

Error de dependencia circular de Spirng: ¿Hay una referencia circular sin resolver?

Recientemente, encontré un error de dependencia circular en mi proyecto. Aunque se resolvió rápidamente, todavía hay algunas cosas que no entiendo, así que quiero registrarlas aquí.

Aquí, separo la estructura del bean y el método de inyección para demostración.

Haga clic para ir a la descripción del problema de desbordamiento de pila

BrokenComponent:

TolenComponent:

TubunComponent:

TwConfig:

DenpaComponent:

Excepto tubunComponent que es inyectado por el constructor, otros beans son Collection inyección.

El análisis del gráfico de dependencia de beans puede revelar que efectivamente existe un problema de dependencia circular.

Como no entendía claramente el mecanismo de carga de Spring Bean, pasé unos días resolviendolo.

¿Qué problema se solucionó?

Blog recomendado: /developer/article/1497692

Función: Complete las propiedades del Bean creado por BeanFactory.

Aquí está el fragmento de código para el método AbstractAutowireCapableBeanFactory#populateBean:

Escribí todos los BeanPostProcessors que quiero sondear para ver si hay sumas de comprobación

En BrokenComponent.bean hay son dos:

Uno se inyecta a través de la anotación @Resource y el otro se inyecta a través de @Autowire, ¡así que no mezcle los dos!

Después de la traducción y la depuración, la clase completará todas las propiedades del bean modificado mediante la anotación @Resource.

Esta clase completará todas las propiedades del Bean modificado mediante la anotación @Autowire@Value.

1: Ya sea que use @Resource o @Resource, no afectará el orden de inicialización del bean.

2: Las propiedades modificadas a través de @Resource tienen prioridad sobre las propiedades modificadas a través de @Autowire.

Puedes ver que tubunComponent ejecuta getSingleton dos veces y genera errores al pasar la verificación de dependencia circular.

1: El contenedor Spring carga primero el bean BrokenComponent.

2: BrokenComponent depende de tubunComponent (@Resource modifier), por lo que primero completa tubunComponent y, por lo tanto, inicializa Bean tubunComponent y almacena tubunComponent en la colección DefaultSingletonBeanRegistry.singletonsCurrentlyInCreation.

3: tubunComponent depende de depenComponent, así que inicialice Bean DepenComponent y almacene depenComponent en la colección DefaultSingletonBeanRegistry.singletonsCurrentlyInCreation.

4: depenComponent depende de tolenComponent, así que inicialice el bean depenComponent y almacene tolenComponent en la colección DefaultSingletonBeanRegistry.singletonsCurrentlyInCreation.

5: torenComponent depende de tubunComponent, por lo que el bean tubunComponent se inicializa, pero cuando tubunComponent se almacena en la colección DefaultSingletonBeanRegistry.singletonsCurrentlyInCreation, tubunComponent ya existe,

Se determina que estos beans tienen relación de dependencias circulares y se lanzó una excepción.

fuente del método beforeSingletonCreation(String beanName):

1: use el modificador @Lazy.

2: En realidad, este es un problema mal manejado, porque el caché de tercer nivel de Spring ha resuelto las dependencias circulares causadas por la inyección de colecciones, y no todos estos beans se inyectan mediante constructores.

Prueba experimental:

Dar prioridad al uso de combinaciones que reporten errores...