Der Spring ApplicationContext

1. Übersicht

In diesem Tutorial werden wir uns ausführlich mit der Spring ApplicationConext- Oberfläche befassen.

2. Die ApplicationContext- Schnittstelle

Eines der Hauptmerkmale des Spring-Frameworks ist der IoC-Container (Inversion of Control). Der Spring IoC-Container ist für die Verwaltung der Objekte einer Anwendung verantwortlich. Es verwendet die Abhängigkeitsinjektion, um eine Umkehrung der Steuerung zu erreichen.

Die Schnittstellen BeanFactory und ApplicationContext repräsentieren den Spring IoC-Container . Hier ist BeanFactory die Root-Schnittstelle für den Zugriff auf den Spring-Container. Es bietet grundlegende Funktionen zum Verwalten von Beans.

Andererseits ist der ApplicationContext eine Unterschnittstelle der BeanFactory . Daher bietet es alle Funktionen von BeanFactory.

Darüber hinaus bietet es mehr unternehmensspezifische Funktionen . Die wichtigen Funktionen von ApplicationContext sind das Auflösen von Nachrichten, die Unterstützung der Internationalisierung, das Veröffentlichen von Ereignissen und spezifische Kontexte auf Anwendungsebene . Aus diesem Grund verwenden wir es als Standard-Spring-Container.

3. Was ist eine Frühlingsbohne?

Bevor wir tiefer in den ApplicationContext- Container eintauchen , ist es wichtig, sich mit Spring Beans vertraut zu machen. In Spring ist eine Bean ein Objekt, das der Spring-Container instanziiert, zusammenstellt und verwaltet .

Sollen wir also alle Objekte unserer Anwendung als Spring Beans konfigurieren? Nun, als Best Practice sollten wir das nicht tun.

Gemäß der Spring-Dokumentation sollten wir im Allgemeinen Beans für Service-Layer-Objekte, Datenzugriffsobjekte (DAOs), Präsentationsobjekte, Infrastrukturobjekte wie Hibernate SessionFactories, JMS-Warteschlangen usw. definieren.

Außerdem sollten wir normalerweise keine feinkörnigen Domänenobjekte im Container konfigurieren. Es liegt normalerweise in der Verantwortung von DAOs und Geschäftslogik, Domänenobjekte zu erstellen und zu laden.

Definieren wir also eine einfache Java-Klasse, die wir in diesem Tutorial als Spring Bean verwenden:

public class AccountService { @Autowired private AccountRepository accountRepository; // getters and setters }

4. Bohnen im Container konfigurieren

Wie wir wissen, besteht die Hauptaufgabe des ApplicationContext darin, Beans zu verwalten.

Daher muss eine Anwendung die Bean-Konfiguration für den ApplicationContext- Container bereitstellen . Daher besteht eine Spring-Bean-Konfiguration aus einer oder mehreren Bean-Definitionen. Außerdem unterstützt Spring verschiedene Arten der Konfiguration von Beans.

4.1. Java-basierte Konfiguration

Zunächst beginnen wir mit der Java-basierten Konfiguration, da dies die neueste und am meisten bevorzugte Methode zur Bean-Konfiguration ist. Es ist ab Frühjahr 3.0 verfügbar.

Die Java-Konfiguration verwendet normalerweise @ Bean- annotierte Methoden innerhalb einer @ Configuration- Klasse . Die Annotation @Bean für eine Methode gibt an, dass die Methode eine Spring Bean erstellt. Darüber hinaus gibt eine mit @Configuration annotierte Klasse an, dass sie Spring Bean-Konfigurationen enthält.

Erstellen wir nun eine Konfigurationsklasse, um unsere AccountService- Klasse als Spring Bean zu definieren :

@Configuration public class AccountConfig { @Bean public AccountService accountService() { return new AccountService(accountRepository()); } @Bean public AccountRepository accountRepository() { return new AccountRepository(); } }

4.2. Anmerkungsbasierte Konfiguration

In Spring 2.5 wurde die annotationsbasierte Konfiguration als erster Schritt eingeführt, um Bean-Konfigurationen in Java zu aktivieren.

Bei diesem Ansatz aktivieren wir zunächst die annotationsbasierte Konfiguration über die XML-Konfiguration. Anschließend verwenden wir eine Reihe von Anmerkungen zu unseren Java-Klassen, -Methoden, -Konstruktoren oder -Feldern, um Beans zu konfigurieren. Einige Beispiele für diese Anmerkungen sind @Component , @Controller , @Service , @Repository , @Autowired und @Qualifier .

Insbesondere verwenden wir diese Anmerkungen auch mit Java-basierter Konfiguration. Außerdem fügt Spring diesen Anmerkungen mit jeder Version weitere Funktionen hinzu.

Schauen wir uns nun ein einfaches Beispiel für diese Konfiguration an.

Zuerst erstellen wir die XML-Konfiguration user-bean-config.xml , um Anmerkungen zu aktivieren:

Hier die Annotation-config ermöglicht Tag Annotation-basierte Zuordnungen . Außerdem teilt das Komponenten-Scan- Tag Spring mit, wo nach kommentierten Klassen gesucht werden soll.

Zweitens erstellen wir die UserService- Klasse und definieren sie mithilfe der Annotation @Component als Spring Bean :

@Component public class UserService { // user service code }

Und dann schreiben wir einen einfachen Testfall, um diese Konfiguration zu testen:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/user-bean-config.xml"); UserService userService = context.getBean(UserService.class); assertNotNull(userService);

4.3. XML-basierte Konfiguration

Schauen wir uns zum Schluss die XML-basierte Konfiguration an. Dies ist die traditionelle Art, Bohnen im Frühjahr zu konfigurieren.

Offensichtlich führen wir bei diesem Ansatz alle Bean-Zuordnungen in einer XML-Konfigurationsdatei durch .

Erstellen wir also eine XML-Konfigurationsdatei, account-bean-config.xml , und definieren Beans für unsere AccountService- Klasse:

5. Arten von ApplicationContext

Spring bietet verschiedene Arten von ApplicationContext- Containern, die für unterschiedliche Anforderungen geeignet sind. Dies sind Implementierungen der ApplicationContext- Schnittstelle. Schauen wir uns also einige der gängigen Arten von ApplicationContext an .

5.1. AnnotationConfigApplicationContext

First, let's see the AnnotationConfigApplicationContext class, which was introduced in Spring 3.0. It can take classes annotated with @Configuration, @Component, and JSR-330 metadata as input.

So, let's see a simple example of using the AnnotationConfigApplicationContext container with our Java-based configuration:

ApplicationContext context = new AnnotationConfigApplicationContext(AccountConfig.class); AccountService accountService = context.getBean(AccountService.class);

5.2. AnnotationConfigWebApplicationContext

AnnotationConfigWebApplicationContextis a web-based variant of AnnotationConfigApplicationContext.

We may use this class when we configure Spring's ContextLoaderListener servlet listener or a Spring MVC DispatcherServlet, in a web.xml file.

Moreover, from Spring 3.0 onward, we can also configure this application context container programmatically. All we need to do is to implement the WebApplicationInitializer interface:

public class MyWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(AccountConfig.class); context.setServletContext(container); // servlet configuration } }

5.3. XmlWebApplicationContext

If we use the XML based configuration in a web application, we can use the XmlWebApplicationContext class.

As a matter of fact, configuring this container is like the AnnotationConfigWebApplicationContext class only, which means we can configure it in web.xml or implement the WebApplicationInitializer interface:

public class MyXmlWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { XmlWebApplicationContext context = new XmlWebApplicationContext(); context.setConfigLocation("/WEB-INF/spring/applicationContext.xml"); context.setServletContext(container); // Servlet configuration } }

5.4. FileSystemXMLApplicationContext

We use the FileSystemXMLApplicationContext class to load an XML-based Spring configuration file from the file system or from URLs. This class is useful when we need to load the ApplicationContext programmatically. In general, test harnesses and standalone applications are some of the possible use cases for this.

For example, let's see how we can create this Spring container and load the beans for our XML-based configuration:

String path = "C:/myProject/src/main/resources/applicationcontext/account-bean-config.xml"; ApplicationContext context = new FileSystemXmlApplicationContext(path); AccountService accountService = context.getBean("accountService", AccountService.class);

5.5. ClassPathXmlApplicationContext

In case we want to load an XML configuration file from the classpath, we can use the ClassPathXmlApplicationContext class. Similar to FileSystemXMLApplicationContext, it's useful for test harnesses as well as for application contexts embedded within JARs.

So, let's see an example of using this class:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/account-bean-config.xml"); AccountService accountService = context.getBean("accountService", AccountService.class);

6. Additional Features of ApplicationContext

6.1. Message Resolution

The ApplicationContext interface supports message resolution and internationalization by extending the MessageSource interface. Furthermore, Spring provides two MessageSource implementations, ResourceBundleMessageSource and StaticMessageSource.

We can use the StaticMessageSource to programmatically add messages to the source. However, it supports basic internationalization and is more suitable for tests than production use.

On the other hand, ResourceBundleMessageSource is the most common implementation of MessageSource. It relies on the underlying JDK's ResouceBundle implementation. It also uses the JDK's standard message parsing provided by MessageFormat.

Now, let's see how can we use the MessageSource to read the messages from a properties file.

First, we'll create the messages.properties file on the classpath:

account.name=TestAccount

Second, we'll add a bean definition in our AccountConfig class:

@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("config/messages"); return messageSource; }

Third, we'll inject the MessageSource in the AccountService:

@Autowired private MessageSource messageSource;

Finally, we can use the getMessage method anywhere in the AccountService to read the message:

messageSource.getMessage("account.name", null, Locale.ENGLISH);

Spring also provides the ReloadableResourceBundleMessageSource class, which allows for reading files from any Spring resource location and supports hot reloading of bundle property files.

6.2. Event Handling

ApplicationContext supports event handling with the help of the ApplicationEvent class and the ApplicationListener interface. It supports built-in events like ContextStartedEvent, ContextStoppedEvent, ContextClosedEvent, and RequestHandledEvent. Moreover, it also supports custom events for business use cases.

7. Conclusion

In this tutorial, we've discussed various aspects of the ApplicationContext container in Spring. We've seen different examples of how to configure Spring beans in an AppicationContext. Also, we've seen how to create and use different types of ApplicationContext.

Wie immer ist der vollständige Code auf GitHub verfügbar.