Was ist bei dem Problem „java.lang.IllegalStateException: Fehler beim Laden des ApplicationContext“ zu tun?

Heute bin ich auf ein Problem gestoßen, das mich schon seit einiger Zeit beschäftigt: java.lang.IllegalStateException: Fehler beim Laden des ApplicationContext. Dies ist ein sehr häufiger Fehler im Spring-Framework. Er wird normalerweise durch Probleme mit der Abhängigkeitsinjektion verursacht, die genaue Ursache ist jedoch nicht leicht zu lokalisieren. Hier möchte ich mit Ihnen teilen, wie ich dieses Problem gelöst habe.

Zuerst müssen wir verstehen, was dieser Fehler bedeutet. Wenn dieser Fehler auftritt, gibt es normalerweise eine Reihe von Informationen, die den genauen Ort und die Ursache des Fehlers enthalten. Zum Beispiel die folgenden Informationen:

java.lang.IllegalStateException: Failed to load ApplicationContext
 at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
 at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
 at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
 ...
 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.SampleService com.example.SampleController.sampleService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.SampleService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 ...
 Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.SampleService com.example.SampleController.sampleService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.SampleService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 ...
 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.SampleService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Diese Informationen sagen uns, dass das Problem im Feld „sampleService“ in der Klasse „SampleController“ auftritt und Spring die diesem Feld entsprechende Bean nicht finden kann. Doch was ist die Ursache des Problems? Wird die SampleService-Klasse nicht gescannt? Oder ist es in der Spring-Konfigurationsdatei nicht richtig konfiguriert?

Um dieses Problem zu lösen, müssen wir einige Fehlerbehebungen durchführen. Zuerst müssen wir einen Blick auf unseren Code werfen, um festzustellen, ob ein Problem vorliegt. Hier ist der Code, den ich hatte, als ich auf dieses Problem stieß:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SampleConfig.class})
public class SampleControllerTest {

    @Autowired
    private SampleController sampleController;

    @Test
    public void test() {
        Assert.assertNotNull(sampleController);
    }
}

Wir können sehen, dass es sich hierbei um eine Spring-Unit-Test-Klasse handelt, die die Annotationen SpringJUnit4ClassRunner und @ContextConfiguration verwendet. Die Annotation @ContextConfiguration wird verwendet, um die Spring-Konfigurationsdatei anzugeben. Hier wird SampleConfig.class verwendet. Zum Testen haben wir auch eine Instanz der SampleController-Klasse eingefügt. In der Testmethode haben wir eine NotNull-Beurteilung des SampleControllers vorgenommen.

Den Informationen zufolge tritt das Problem im Feld „sampleService“ in SampleController auf. Wir können einen Blick auf den SampleController-Code werfen, um festzustellen, ob ein Problem vorliegt.

@Controller
public class SampleController {

    @Autowired
    private SampleService sampleService;

    @RequestMapping(value = "/")
    public String index(Model model) {
        model.addAttribute("message", sampleService.getMessage());
        return "index";
    }
}

Wir können sehen, dass die Annotation @Autowired in SampleController verwendet wird, um eine Instanz von SampleService einzufügen, und dass dann die getMessage-Methode der Instanz in der Indexmethode verwendet wird, um Daten abzurufen. An diesem Code scheint nichts falsch zu sein, daher liegt das Problem wahrscheinlich in der SampleService-Klasse.

@Service
public class SampleService {

    public String getMessage() {
        return "Hello, World!";
    }
}

Wir können sehen, dass es in SampleService nur eine einfache getMessage-Methode gibt, die einen String zurückgibt. Für diese Klasse gibt es keine besonderen Anmerkungen oder Konfigurationen.

Daher ist es wahrscheinlich, dass wir ein Problem in der Konfigurationsdatei von Spring haben. Werfen wir einen Blick auf den Code der SampleConfig-Klasse.

@Configuration
@ComponentScan(basePackages = {"com.example"})
public class SampleConfig {

}

Wir können sehen, dass dies eine Spring-Konfigurationsklasse ist, die die Annotation @Configuration verwendet und @ComponentScan verwendet, um die Pakete anzugeben, die Spring scannt. Wir haben hier das Paket com.example angegeben, daher sollte Spring alle Klassen unter diesem Paket scannen und diese Klassen automatisch zusammenstellen.

Hier liegt jedoch das Problem. Wir verwenden die Annotation @ComponentScan, um Pakete zu scannen. Diese Annotation ist nicht allmächtig. Sie scannt nur Klassen, die mit @Component, @Service, @Repository, @Controller oder @ControllerAdvice annotiert sind. In SampleService verwenden wir keine dieser Anmerkungen, daher scannt Spring diese Klasse nicht automatisch.

Um dieses Problem zu lösen, müssen wir eine andere Annotation verwenden – @Service. Die Annotation @Service wird einer Service-Klasse mit Anmerkungen versehen, was darauf hinweist, dass diese Klasse eine Komponente der Geschäftslogikschicht ist. Wenn wir die Annotation @ComponentScan in der Konfigurationsdatei von Spring verwenden, um Pakete zu scannen, scannt Spring auch die mit @Service annotierten Klassen und erstellt eine Bean-Instanz für sie.

Ändern Sie die SampleService-Klasse und fügen Sie die Annotation @Service hinzu:

@Service
public class SampleService {

    public String getMessage() {
        return "Hello, World!";
    }
}

Führen Sie den Komponententest erneut aus. Das Problem ist gelöst und es werden keine Fehler mehr gemeldet.

Zusammenfassend lässt sich sagen, dass wir, wenn wir auf den Fehler java.lang.IllegalStateException: Failed to load ApplicationContext stoßen, zunächst die Informationen überprüfen müssen, um zu verstehen, wo und warum der Fehler aufgetreten ist. Anschließend müssen Sie Ihren eigenen Code und die Spring-Konfigurationsdateien kombinieren, um das Problem zu beheben und herauszufinden. Während dieses Prozesses können Sie auf die offizielle Dokumentation und zugehörige Materialien zurückgreifen, um die Funktionsweise von Spring besser zu verstehen.

おすすめ

転載: blog.csdn.net/javamendou/article/details/131403440
おすすめ