Einführung in den Spring ClassPathXmlApplicationContext

1. Überblick

Der Spring Framework-Kern ist einfach ein IoC-Container, der zur Verwaltung von Beans verwendet wird.

In Spring gibt es zwei grundlegende Arten von Containern - die Bean Factory und den Anwendungskontext. Ersteres stellt grundlegende Funktionalitäten zur Verfügung, die eingeführt werden:/spring-beanfactory[hier]; Letzteres ist eine Obermenge des Ersteren und wird am häufigsten verwendet.

ApplicationContext ist eine Schnittstelle im Paket org.springframework.context , und es gibt mehrere Implementierungen, und ClassPathXmlApplicationContext ist eine davon.

In diesem Artikel konzentrieren wir uns auf die nützlichen Funktionen, die von ClassPathXmlApplicationContext bereitgestellt werden.

2. Grundnutzung

2.1. Container initialisieren und Bohnen verwalten

ClassPathXmlApplicationContext kann eine XML-Konfiguration aus einem Klassenpfad laden und seine Beans verwalten:

Wir haben eine Student -Klasse:

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

   //standard constructors, getters and setters
}

Wir konfigurieren eine Student -Bean in classpathxmlapplicationcontext-example.xml und fügen sie einem Klassenpfad hinzu:

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

Jetzt können wir mit ClassPathXmlApplicationContext die XML-Konfiguration laden und die Student -Bean abrufen:

@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. Mehrere XML-Konfigurationen

Manchmal möchten wir mehrere XML-Konfigurationen verwenden, um einen Spring-Container zu initialisieren. In diesem Fall müssen Sie beim Erstellen des ApplicationContext einfach mehrere Konfigurationspositionen hinzufügen:

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

3. Zusatzfunktionen

3.1. Fahren Sie den Spring-IoC-Container mit Grazie herunter

Wenn wir Spring-IoC-Container in einer Webanwendung verwenden, wird der Container durch die webbasierten ApplicationContext -Implementierungen von Spring ordnungsgemäß heruntergefahren, wenn die Anwendung heruntergefahren wird. Wenn wir ihn jedoch in einer Nicht-Web-Umgebung verwenden, z Sie müssen selbst einen Shutdown-Hook bei der JVM registrieren, um sicherzustellen, dass der Spring-IoC-Container ordnungsgemäß heruntergefahren wird und die Zerstörungsmethoden aufruft, um Ressourcen freizugeben.

Fügen wir der Student -Klasse eine destroy () -Methode hinzu:

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

Wir können diese Methode nun als destroy-Methode der student -Bean konfigurieren:

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

Jetzt registrieren wir einen Shutdown Hook:

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

Wenn wir die Testmethode ausführen, wird die Methode destroy () aufgerufen.

3.2. Internationalisierung mit MessageSource

Die ApplicationContext -Schnittstelle erweitert die MessageSource -Schnittstelle und bietet daher Internationalisierungsfunktionalität.

Ein ApplicationContext -Container sucht bei seiner Initialisierung automatisch nach einer MessageSource -Bean, und die Bean muss als messageSource benannt werden.

Hier ein Beispiel für die Verwendung verschiedener Sprachen mit MessageSource :

Fügen wir zunächst ein dialog -Verzeichnis in einen Klassenpfad ein und fügen Sie zwei Dateien in das Dialogverzeichnis ein: dialog en.properties und 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}

Konfigurieren Sie die messageSource -Bean in 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>

Dann lassen Sie uns mit MessageSource Dialogwörter aus verschiedenen Sprachen erhalten:

@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. Ein Verweis auf den ApplicationContext

Manchmal benötigen wir die Referenz von ApplicationContext in den von ihr verwalteten Beans. Wir können dazu ApplicationContextAware oder @ Autowired verwenden. Mal sehen, wie die Verwendung von ApplicationContextAware funktioniert:

Wir haben eine Course -Klasse mit einem Namen:

public class Course {

    private String name;

   //standard constructors, getters and setters
}

Wir haben eine Teacher -Klasse, die ihre Kurse entsprechend den Beans des Containers zusammenstellt:

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
}

Lassen Sie uns die course -Bean und die teacher -Bean in classpathxmlapplicationcontext-example.xml konfigurieren:

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

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

Dann testen Sie die Injektion der courses -Eigenschaft:

@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"));
}

Neben der Implementierung der Schnittstelle ApplicationContextAware hat die Verwendung der Annotation @ Autowired die gleiche Wirkung.

Ändern wir die Teacher -Klasse folgendermaßen:

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
}

Führen Sie dann diesen Test aus. Wir können sehen, dass das Ergebnis das gleiche ist.

5. Fazit

ApplicationContext ist ein Spring-Container mit mehr unternehmensspezifischen Funktionen im Vergleich zu BeanFactory , und der ClassPathXmlApplicationContext ist eine der am häufigsten verwendeten Implementierungen.

Daher haben wir in diesem Artikel einige Aspekte des ClassPathXmlApplicationContext vorgestellt, einschließlich der grundlegenden Verwendung, der Registrierungsfunktionalität zum Herunterfahren, der Internationalisierungsfunktionalität und des Bezugs auf dessen Referenz.

Der vollständige Quellcode für das Beispiel ist wie immer verfügbar: over auf GitHub .