Le contexte de l'application Spring

1. Vue d'ensemble

Dans ce didacticiel, nous examinerons en détail l'interface Spring ApplicationConext .

2. L' interface ApplicationContext

L'une des principales fonctionnalités du framework Spring est le conteneur IoC (Inversion of Control). Le conteneur Spring IoC est responsable de la gestion des objets d'une application. Il utilise l'injection de dépendances pour obtenir une inversion de contrôle.

Les interfaces BeanFactory et ApplicationContext représentent le conteneur Spring IoC . Ici, BeanFactory est l'interface racine pour accéder au conteneur Spring. Il fournit des fonctionnalités de base pour la gestion des beans.

D'autre part, l' ApplicationContext est une sous-interface de BeanFactory . Ainsi, il offre toutes les fonctionnalités de BeanFactory.

En outre, il fournit des fonctionnalités plus spécifiques à l'entreprise . Les fonctionnalités importantes d' ApplicationContext sont la résolution des messages, la prise en charge de l'internationalisation, la publication d'événements et les contextes spécifiques à la couche application . C'est pourquoi nous l'utilisons comme conteneur Spring par défaut.

3. Qu'est-ce qu'un haricot printanier?

Avant de plonger plus profondément dans le conteneur ApplicationContext , il est important de connaître les beans Spring. Dans Spring, un bean est un objet que le conteneur Spring instancie, assemble et gère .

Alors, devons-nous configurer tous les objets de notre application en tant que Spring beans? Eh bien, comme meilleure pratique, nous ne devrions pas.

Selon la documentation Spring, en général, nous devons définir des beans pour les objets de couche de service, les objets d'accès aux données (DAO), les objets de présentation, les objets d'infrastructure tels que Hibernate SessionFactories, les files d'attente JMS, etc.

En outre, généralement, nous ne devons pas configurer d'objets de domaine à granularité fine dans le conteneur. Il incombe généralement aux DAO et à la logique métier de créer et de charger des objets de domaine.

Alors, définissons une classe Java simple que nous utiliserons comme bean Spring dans ce tutoriel:

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

4. Configuration des beans dans le conteneur

Comme nous le savons, le travail principal d' ApplicationContext est de gérer les beans.

Ainsi, une application doit fournir la configuration du bean au conteneur ApplicationContext . Par conséquent, une configuration de bean Spring se compose d'une ou plusieurs définitions de bean. De plus, Spring prend en charge différentes manières de configurer les beans.

4.1. Configuration basée sur Java

Tout d'abord, nous allons commencer par la configuration basée sur Java car c'est le moyen le plus récent et le plus préféré de configuration de bean. Il est disponible à partir du printemps 3.0.

La configuration Java utilise généralement des méthodes annotées @Bean dans une classe @Configuration . L' annotation @Bean sur une méthode indique que la méthode crée un bean Spring. De plus, une classe annotée avec @Configuration indique qu'elle contient des configurations de bean Spring.

Alors, créons maintenant une classe de configuration pour définir notre classe AccountService comme un bean Spring:

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

4.2. Configuration basée sur les annotations

Spring 2.5 a introduit la configuration basée sur les annotations comme première étape pour activer les configurations de bean en Java.

Dans cette approche, nous activons d'abord la configuration basée sur les annotations via la configuration XML. Ensuite, nous utilisons un ensemble d'annotations sur nos classes, méthodes, constructeurs ou champs Java pour configurer les beans. Quelques exemples de ces annotations sont @Component , @Controller , @Service , @Repository , @Autowired et @Qualifier .

Notamment, nous utilisons également ces annotations avec une configuration basée sur Java. En outre, Spring continue d'ajouter plus de fonctionnalités à ces annotations à chaque version.

Alors, maintenant, voyons un exemple simple de cette configuration.

Tout d'abord, nous allons créer la configuration XML, user-bean-config.xml , pour activer les annotations:

Ici, la balise annotation-config active les mappages basés sur les annotations . En outre, la balise d' analyse des composants indique à Spring où rechercher les classes annotées.

Deuxièmement, nous allons créer la classe UserService et la définir comme un bean Spring à l'aide de l' annotation @Component :

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

Et puis, nous allons écrire un cas de test simple pour tester cette configuration:

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

4.3. Configuration basée sur XML

Enfin, jetons un œil à la configuration basée sur XML. C'est la manière traditionnelle de configurer les beans au printemps.

Évidemment, dans cette approche, nous effectuons tous les mappages de bean dans un fichier de configuration XML .

Alors, créons un fichier de configuration XML, account-bean-config.xml , et définissons des beans pour notre classe AccountService :

5. Types d' ApplicationContext

Spring fournit différents types de conteneurs ApplicationContext adaptés à différentes exigences. Ce sont des implémentations de l' interface ApplicationContext . Jetons donc un coup d'œil à certains des types courants d' ApplicationContext .

5.1. AnnotationConfigApplicationContext

Tout d'abord, voyons la classe AnnotationConfigApplicationContext , qui a été introduite dans Spring 3.0. Il peut prendre des cours annotés avec @Configuration , @component , et les métadonnées JSR-330 en entrée.

Voyons donc un exemple simple d'utilisation du conteneur AnnotationConfigApplicationContext avec notre configuration basée sur Java:

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

5.2. AnnotationConfigWebApplicationContext

AnnotationConfigWebApplicationContext est une variante Web de AnnotationConfigApplicationContext .

Nous pouvons utiliser cette classe lorsque nous configurons l' écouteur de servlet ContextLoaderListener de Spring ou un DispatcherServlet Spring MVC , dans un fichier web.xml .

De plus, à partir de Spring 3.0, nous pouvons également configurer ce conteneur de contexte d'application par programme. Tout ce que nous devons faire est d'implémenter l' interface WebApplicationInitializer :

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

Si nous utilisons la configuration basée sur XML dans une application Web , nous pouvons utiliser la classe XmlWebApplicationContext .

En fait, la configuration de ce conteneur est comme la classe AnnotationConfigWebApplicationContext uniquement, ce qui signifie que nous pouvons le configurer dans web.xml ou implémenter l' interface WebApplicationInitializer :

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

Nous utilisons la classe FileSystemXMLApplicationContext pour charger un fichier de configuration Spring basé sur XML à partir du système de fichiers ou des URL. Cette classe est utile lorsque nous devons charger l' ApplicationContext par programme. En général, les faisceaux de test et les applications autonomes sont quelques-uns des cas d'utilisation possibles pour cela.

Par exemple, voyons comment nous pouvons créer ce conteneur Spring et charger les beans pour notre configuration XML:

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.

Comme toujours, le code complet est disponible à l'adresse over sur GitHub.