Introduction au Spring ClassPathXmlApplicationContext

1. Vue d’ensemble

En résumé, le cadre Spring est un conteneur IoC utilisé pour gérer les beans.

Il existe deux types de base de conteneurs dans Spring: l’usine de haricots et le contexte d’application. Le premier fournit des fonctionnalités de base, qui sont introduites lien:/spring-beanfactory[ici]; le dernier est un sur-ensemble du premier et est le plus largement utilisé.

ApplicationContext est une interface du package org.springframework.context . Elle comporte plusieurs implémentations, et ClassPathXmlApplicationContext en fait partie.

Dans cet article, nous allons nous concentrer sur les fonctionnalités utiles fournies par ClassPathXmlApplicationContext .

2. Utilisation de base

2.1. Initialiser le conteneur et gérer les haricots

ClassPathXmlApplicationContext peut charger une configuration XML à partir d’un chemin de classe et gérer ses beans:

Nous avons une classe Student :

public class Student {
    private int no;
    private String name;

   //standard constructors, getters and setters
}

Nous configurons un bean Student dans classpathxmlapplicationcontext-example.xml et nous l’ajoutons à un chemin de classe:

<beans ...>
    <bean id="student" class="com.baeldung.applicationcontext.Student">
        <property name="no" value="15"/>
        <property name="name" value="Tom"/>
    </bean>
</beans>

Nous pouvons maintenant utiliser ClassPathXmlApplicationContext pour charger la configuration XML et obtenir le bean Student :

@Test
public void testBasicUsage() {
    ApplicationContext context
      = new ClassPathXmlApplicationContext(
        "classpathxmlapplicationcontext-example.xml");

    Student student = (Student) context.getBean("student");
    assertThat(student.getNo(), equalTo(15));
    assertThat(student.getName(), equalTo("Tom"));

    Student sameStudent = context.getBean("student", Student.class);
    assertThat(sameStudent.getNo(), equalTo(15));
    assertThat(sameStudent.getName(), equalTo("Tom"));
}

2.2. Configurations XML multiples

Parfois, nous souhaitons utiliser plusieurs configurations XML pour initialiser un conteneur Spring. Dans ce cas, nous devons simplement ajouter plusieurs emplacements de configuration lors de la construction de ApplicationContext :

ApplicationContext context
  = new ClassPathXmlApplicationContext("ctx.xml", "ctx2.xml");

3. Capacités supplémentaires

3.1. Fermez le conteneur Spring IoC avec élégance

Lorsque nous utilisons le conteneur Spring IoC dans une application Web, les implémentations ApplicationContext Web de Spring vont fermer le conteneur normalement lorsque l’application est arrêtée, mais si devez enregistrer nous-mêmes un point d’arrêt avec la machine virtuelle Java pour nous assurer que le conteneur Spring IoC est fermé correctement et qu’il appelle les méthodes de destruction pour libérer des ressources.

Ajoutons une méthode destroy () à la classe Student :

public void destroy() {
    System.out.println("Student(no: " + no + ") is destroyed");
}

Nous pouvons maintenant configurer cette méthode comme méthode de destruction de student bean:

<beans ...>
    <bean id="student" class="com.baeldung.applicationcontext.Student"
      destroy-method="destroy">
        <property name="no" value="15"/>
        <property name="name" value="Tom"/>
    </bean>
</beans>

Nous allons maintenant enregistrer un crochet d’arrêt:

@Test
public void testRegisterShutdownHook() {
    ConfigurableApplicationContext context
      = new ClassPathXmlApplicationContext(
        "classpathxmlapplicationcontext-example.xml");
    context.registerShutdownHook();
}

Lorsque nous exécutons la méthode de test, nous pouvons voir que la méthode destroy () est appelée.

3.2. Internationalisation avec MessageSource

L’interface ApplicationContext étend l’interface MessageSource et fournit donc une fonctionnalité d’internationalisation.

Un conteneur ApplicationContext recherche automatiquement un bean MessageSource dans son initialisation, et le bean doit être nommé messageSource .

Voici un exemple d’utilisation de différentes langues avec MessageSource :

Commençons par ajouter un répertoire dialog dans un chemin de classe et deux fichiers dans le répertoire de dialogue: dialog en.properties et dialog zh CN.properties__.

dialog en.properties__:

hello=hello
you=you
thanks=thank {0}

dialog zh CN.properties :

hello=\u4f60\u597d
you=\u4f60
thanks=\u8c22\u8c22{0}

Configurez le bean messageSource dans classpathxmlapplicationcontext-internationalization.xml :

<beans ...>
    <bean id="messageSource"
      class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>dialog/dialog</value>
            </list>
        </property>
    </bean>
</beans>

Récupérons ensuite les mots de dialogue de différentes langues avec MessageSource

@Test
public void testInternationalization() {
    MessageSource resources
      = new ClassPathXmlApplicationContext(
        "classpathxmlapplicationcontext-internationalization.xml");

    String enHello = resources.getMessage(
      "hello", null, "Default", Locale.ENGLISH);
    String enYou = resources.getMessage(
      "you", null, Locale.ENGLISH);
    String enThanks = resources.getMessage(
      "thanks", new Object[]{ enYou }, Locale.ENGLISH);

    assertThat(enHello, equalTo("hello"));
    assertThat(enThanks, equalTo("thank you"));

    String chHello = resources.getMessage(
      "hello", null, "Default", Locale.SIMPLIFIED__CHINESE);
    String chYou = resources.getMessage(
      "you", null, Locale.SIMPLIFIED__CHINESE);
    String chThanks = resources.getMessage(
      "thanks", new Object[]{ chYou }, Locale.SIMPLIFIED__CHINESE);

    assertThat(chHello, equalTo("你好"));
    assertThat(chThanks, equalTo("谢谢你"));
}

4. Une référence à ApplicationContext

Parfois, nous devons obtenir la référence de ApplicationContext à l’intérieur des beans gérés par celui-ci. Nous pouvons utiliser ApplicationContextAware ou @ Autowired pour le faire. Voyons comment utiliser ApplicationContextAware :

Nous avons une classe Course avec un nom:

public class Course {

    private String name;

   //standard constructors, getters and setters
}

Nous avons une classe Teacher qui assemble ses cours en fonction des haricots du conteneur:

public class Teacher implements ApplicationContextAware {

    private ApplicationContext context;
    private List<Course> courses = new ArrayList<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    @PostConstruct
    public void addCourse() {
        if (context.containsBean("math")) {
            Course math = context.getBean("math", Course.class);
            courses.add(math);
        }
        if (context.containsBean("physics")) {
            Course physics = context.getBean("physics", Course.class);
            courses.add(physics);
        }
    }

   //standard constructors, getters and setters
}

Configurons le bean course et le teacher dans classpathxmlapplicationcontext-example.xml :

<beans ...>
    <bean id="math" class="com.baeldung.applicationcontext.Course">
        <property name="name" value="math"/>
    </bean>

    <bean name="teacher" class="com.baeldung.applicationcontext.Teacher"/>
</beans>

Puis - testez l’injection de la propriété courses :

@Test
public void testApplicationContextAware() {
    ApplicationContext context
       = new ClassPathXmlApplicationContext(
         "classpathxmlapplicationcontext-example.xml");
    Teacher teacher = context.getBean("teacher", Teacher.class);
    List<Course> courses = teacher.getCourses();

    assertThat(courses.size(), equalTo(1));
    assertThat(courses.get(0).getName(), equalTo("math"));
}

Outre l’implémentation de l’interface ApplicationContextAware , l’utilisation de l’annotation @ Autowired a le même effet.

Changeons la classe Teacher en ceci:

public class Teacher {

    @Autowired
    private ApplicationContext context;
    private List<Course> courses = new ArrayList<>();

    @PostConstruct
    public void addCourse() {
        if (context.containsBean("math")) {
            Course math = context.getBean("math", Course.class);
            courses.add(math);
        }
        if (context.containsBean("physics")) {
            Course physics = context.getBean("physics", Course.class);
            courses.add(physics);
        }
    }

   //standard constructors, getters and setters
}

Puis lancez ce test, nous pouvons voir que le résultat est le même.

5. Conclusion

ApplicationContext est un conteneur Spring avec des fonctionnalités plus spécifiques à l’entreprise que BeanFactory , et ClassPathXmlApplicationContext est l’une de ses implémentations les plus utilisées.

Dans cet article, nous avons donc introduit plusieurs aspects de ClassPathXmlApplicationContext , notamment son utilisation de base, sa fonctionnalité d’enregistrement à l’arrêt, sa fonctionnalité d’internationalisation et l’obtention de sa référence.

Comme toujours, le code source complet de l’exemple est disponible à l’adresse over sur GitHub .