Maison > Java > javaDidacticiel > Problème d'exécution de la méthode setApplicationContext de l'interface applicationContextAware et échec de l'obtention des beans Spring

Problème d'exécution de la méthode setApplicationContext de l'interface applicationContextAware et échec de l'obtention des beans Spring

Linda Hamilton
Libérer: 2024-11-23 07:53:34
original
197 Les gens l'ont consulté

Dans cet article, j'aimerais partager un problème que j'ai rencontré récemment et qui, je pense, pourrait vous intéresser.

Quel est le problème ?

Le code source des environnements de test et de production est le même, et les environnements local et de test fonctionnent bien, seul l'environnement de production exécuté avec un NPE d'une classe de service n'a pas pu se charger, ce qui s'est ajouté aux nouvelles exigences. Cette classe hérite de l'interface du package Customize (une boîte à outils auto-développée).

La structure du projet

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

La conception de Customize s'appuie sur Spring pour gérer les API et les services. Avec l'analyse automatique Spring, les classes communes d'ApiEnhancer et ServiceEnhancer sont chargées lors de l'initialisation des classes et obtiennent des instances par ApplicationContext. Le débogage a constaté que lors de leur chargement, ApplicationContext est nul et n'a pas encore été initialisé. Il est initialisé dans la méthode setApplicationContext en implémentant ApplicationContextAware, il est donc supposé que la méthode setApplicationContext n'a pas été exécutée.

Pendant le processus de chargement de la classe ApplicationContextProvider, les méthodes statiques sont chargées dans la zone de méthode pendant la phase d'initialisation. Cependant, lorsque vous utilisez ApplicationContext pour obtenir des instances de beans, les méthodes statiques sont directement invoquées par le nom de la classe. Tant que l'API est créée avant que la mémoire ApplicationContextProvider ne soit allouée dans le tas et instanciée, la méthode setApplicationContext ne sera pas invoquée pour s'initialiser.

L'applicationContextProvider utilise l'annotation @Component, et l'Api utilise l'annotation @RestController, et les deux classes sont dans le même chemin. Cependant, lorsque Spring les analyse et les charge, il n'y a pas d'ordre spécifique, ce qui signifie que chacune des deux classes peut être créée avant l'autre. Dans l'environnement de production, l'API est créée avant l'applicationContextProvider, ce qui fait que lorsque la méthode statique est invoquée directement par le nom de la classe pour obtenir des beans, l'applicationContext n'a PAS été initialisé.

Les solutions

Si la méthode setApplicationContext de la classe d'implémentation de l'interface ApplicationContextAware n'a pas été exécutée, vérifiez d'abord si la classe d'implémentation a été définie sur le chargement différé ou si le projet a configuré le chargement différé global.

Dans ce projet, le problème était dû à l'ordre de création des classes d'implémentation des interfaces ApiEnhancer et ApplicationContextAware, et la classe Api n'est qu'une API RESTful standard qui gère la logique métier et peut être chargée lorsqu'elle est invoquée par le front- page de fin. Par conséquent, le passage au chargement différé a résolu le problème.

Il est conseillé de minimiser la relation de dépendance entre les classes en termes d'ordre de chargement. Si cela est inévitable, un chargement paresseux ou des annotations telles que @DependsOn, @Order, @Priority peuvent être utilisées pour contrôler l'ordre de chargement des beans.


Pourquoi l'ordre de création de l'environnement de production et de l'environnement de test est-il différent ?

Déboguons pour vérifier le processus d'analyse de Spring.

En commençant par la méthode d'analyse de ClassPathBeanDeterminationScanner.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

Méthode doScan

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

Méthode scanCandidateComponents de ClassPathScanningCandidateComponentProvider

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

Méthode findAllClassPathResources de PathMatchingResourcePatternResolver

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

Méthode doFindPathMatchingJarResources

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

JarFile est une classe de la bibliothèque standard Java sous le package java.util.jar, qui hérite et étend ZipFile. jarFile.entries() renvoie un itérateur nommé JarEntryIterator.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

JarExitIterator est une implémentation du Iterator Pattern, qui itère sur les entrées de la classe parent de JarFile.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

La méthode d'entrées de ZipFile renvoie un itérateur nommé ZipExitIterator.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

La méthode nextElement de ZipExitIterator appelle la méthode next, qui à son tour appelle la méthode getNextEntry.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

getNextEntry est une méthode native.

The setApplicationContext method execution issue of the applicationContextAware interface and failed to get Spring beans

La méthode native est implémentée dans des langages non Java et invoquée au sein de la machine virtuelle Java pour implémenter les fonctionnalités sous-jacentes, qui peuvent varier en fonction de l'environnement (système d'exploitation ou version JDK). Les packages JAR eux-mêmes n'ont pas d'ordre, donc l'ordre de parcours réel peut varier en fonction des différents outils et environnements d'empaquetage JAR.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal