Problema en línea: Dependencia circular de FeignClient y análisis de código fuente

1 reproducción de escena

Relación de dependencia: el lado izquierdo de la línea punteada es la clase implementada, y el lado derecho de la línea punteada es la clase o anotación de la interfaz nativa de Spring.
Normalmente, no hay una dependencia circular, pero en la operación real, el mensaje de excepción: ¿Hay una referencia circular que no se puede resolver?,
informa claramente que puede haber una dependencia circular, y se requiere una mayor investigación del registro de excepciones.
inserte la descripción de la imagen aquí

1.1 FingirCliente

Llame al servicio a través de Fingir.
inserte la descripción de la imagen aquí

1.2 Manejador Interceptor

Cree un nuevo interceptor de tokens.
inserte la descripción de la imagen aquí

1.3 WebMvcConfigurador

Agregar interceptor de tokens.
inserte la descripción de la imagen aquí

1.4 Controlador

La interfaz depende de FeignClient.
inserte la descripción de la imagen aquí

2 opciones

Agregue @Lazy a FeignClient de TokenInterceptor y no cargue FeignClient de TokenInterceptor al iniciar SpringBoot. Una vez iniciado el servicio, se volverá a cargar cuando sea necesario, de modo que no sea necesario verificar repetidamente el FeignClient singleton al iniciar para garantizar que el servicio se inicia normalmente.
inserte la descripción de la imagen aquí

3 análisis

La información de la pila cuando se inicia SpringBoot es la siguiente: se lanza una excepción desde el interior hacia el exterior, y
hay mucha información de excepción, que se puede ver en las secciones.

  • primer párrafo
    org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'rpcApi': dependencia no satisfecha expresada a través del campo 'feignTemplateService'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': dependencia no satisfecha expresada a través del parámetro 0 del método 'setConfigurers'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'webMvcHandler': dependencia no satisfecha expresada a través del campo 'tokenInterceptor'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'tokenInterceptor': Dependencia insatisfecha expresada a través del campo 'templateService'; la excepción anidada es org.springframework.beans.factory.BeanCurrentlyInCreationException: error al crear el bean con el nombre 'com.monkey.tutorial.common.rpc.IFeignTemplateService': el bean solicitado está actualmente en creación: ¿hay una referencia circular irresoluble?

  • segundo parrafo
    Provocado por: org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': dependencia no satisfecha expresada a través del parámetro 0 del método 'setConfigurers'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'webMvcHandler': dependencia no satisfecha expresada a través del campo 'tokenInterceptor'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'tokenInterceptor': dependencia no satisfecha expresada a través del campo 'templateService'; la excepción anidada es org.springframework.beans.factory.BeanCurrentlyInCreationException: error al crear el bean con el nombre 'com.monkey.tutorial.common.rpc.

  • 第三段
    Causado por: org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'webMvcHandler': dependencia no satisfecha expresada a través del campo 'tokenInterceptor'; la excepción anidada es org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'tokenInterceptor': dependencia no satisfecha expresada a través del campo 'templateService'; la excepción anidada es org.springframework.beans.factory.BeanCurrentlyInCreationException: error al crear el bean con el nombre 'com.monkey.tutorial.common.rpc.IFeignTemplateService': el bean solicitado está actualmente en creación: ¿hay una referencia circular irresoluble?

  • 第四段
    Causado por: org.springframework.beans.factory.UnsatisfiedDependencyException: error al crear el bean con el nombre 'tokenInterceptor': dependencia no satisfecha expresada a través del campo 'templateService'; la excepción anidada es org.springframework.beans.factory.BeanCurrentlyInCreationException: error al crear el bean con el nombre 'com.monkey.tutorial.common.rpc.IFeignTemplateService': el bean solicitado está actualmente en creación: ¿hay una referencia circular irresoluble?

  • 第五段
    Causado por: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error al crear el bean con el nombre 'com.monkey.tutorial.common.rpc.IFeignTemplateService': El bean solicitado está actualmente en creación: ¿Hay una referencia circular irresoluble?
    en org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-5.3.6.jar:5.3.6]

3.1 Posicionamiento anormal

Desde el quinto párrafo de la información de excepción, puede ubicar la ubicación donde se lanza la excepción:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation,
este método es la verificación antes de crear un objeto singleton, el código fuente se muestra en la figura a continuación:
inserte la descripción de la imagen aquí
del código fuente, antes de crear un objeto singleton, verificará si el objeto singleton que se creará está en la colección actual hasta beforeSingletonCreation. De acuerdo con la lógica de juicio del código fuente, si el nombre del objeto singleton (beanName ) que se va a crear está en singletonsCurrentlyInCreation, se generará una excepción.

3.2 Esquema de depuración

A través de la ubicación de excepciones y el análisis lógico de las excepciones lanzadas,
la depuración de puntos de interrupción se puede interrumpir antes de SingletonCreation.La siguiente es la información de depuración de varias ubicaciones principales: rpcApi, WebMvcHandler, TokenInterceptor e IFeignTemplateService.

3.2.1 rpc API

La información de depuración del objeto singleton de creación de verificación de rpcApi se muestra en la siguiente figura.En
el lado derecho de la figura, la colección this.singletonsCurrentlyInCreation está vacía, por lo que se puede pasar la verificación.
inserte la descripción de la imagen aquí

3.2.2 IFeignTemplateService

Ingrese la verificación de IFeignTemplateService, porque rpcApi depende de IFeignTemplateService,
por lo tanto, después de completar la verificación de rpcApi, ingresará a la verificación de IFeignTemplateService, el
resultado de la depuración se muestra en la figura a continuación, como se puede ver en la figura, this.singletonsCurrentlyInCreation de IFeignTemplateService ya tiene un elemento rpcApi,
es decir, rpcApi depende de IFeignTemplateService e IFeignTemplateService no está en la colección singletonsCurrentlyInCreation, por lo que se pasa la verificación.

inserte la descripción de la imagen aquí

3.2.3 mvcResourceProvider

A continuación, el paso de verificación será interceptado por mvcResourceUrlProvider, y
la verificación de mvcResourceUrlProvider se realizará primero.
El resultado de la depuración se muestra en la figura a continuación. Se puede ver en la figura que rpcApi e IFeignTemplateService ya existen en this.singletonsCurrentlyInCreation, lo que
indica que rpcApi e IFeignTemplateService dependen de mvcResourceUrlProvder . En este momento, se pasa la verificación,
el núcleo aquí es: IFeignTemplateService se ha agregado a this.singletonsCurrentlyInCreation, que es la introducción del posterior lanzamiento de excepciones .
inserte la descripción de la imagen aquí

3.2.4 webMvcManejador

mvcResourceUrlProvider depende de webMvcHandler.
Después de que mvcResourceUrlProvider pase la verificación, ingresará a la verificación de webMvcHandler.
El resultado de la depuración se muestra en la siguiente figura. Como se puede ver en la figura, webMvcHandler pasó la verificación sin excepción.
inserte la descripción de la imagen aquí

3.2.5 tokenInterceptor

webMvcHandler se basa en tokenInterceptor. Después de verificar webMvcHandler, ingresará a la verificación de tokenInterceptor.
El proceso de verificación de tokenInterceptor se muestra en la siguiente figura y se pasa la verificación.
inserte la descripción de la imagen aquí

3.2.6 IFeignTemplateService

Dado que tokenInterceptor también depende de IFeignTemplateService,
después de verificar tokenInterceptor, continuará verificando IFeignTemplateService. El
proceso de depuración se muestra en la siguiente figura. Según el análisis anterior, IFeignTemplateService ya existe en this.singletonsCurrentlyInCreation (
porque IFeignTemplateService depende de mvcResourceUrlProvider; mvcResourceUrlProvider depende de webMvcHandler)
La validación falla y se genera una excepción.
inserte la descripción de la imagen aquí
Lanzar una excepción
inserte la descripción de la imagen aquí

3.3 Dependencias cíclicas

Después del análisis, la dependencia circular formada se muestra en la siguiente figura.

inserte la descripción de la imagen aquí

3.4 Resolver

Para garantizar el servicio SpringBoot, es necesario romper la dependencia circular.
Por lo tanto, en TokenInterceptor, FeignClieit no se carga cuando se inicia el servicio, y la
anotación @Lazy se agrega a FeignClient para retrasar la carga. Después de que el servicio es iniciado, se carga cuando hay una llamada.
inserte la descripción de la imagen aquí

4 Resumen

(1) Las dependencias cíclicas tienen dependencias explícitas: como A->B->C->A, y dependencias implícitas, que deben depurarse paso a paso; (2)
Soluciones para dependencias circulares: romper el ciclo, ajustar el diseño del código , retrasar la carga, etc.

Supongo que te gusta

Origin blog.csdn.net/Xin_101/article/details/130034641
Recomendado
Clasificación