知識庫 / Spring RSS 訂閱

Spring ClassPathXmlApplicationContext 入門

Spring
HongKong
11
02:43 PM · Dec 06 ,2025

1. 概述

Spring 框架的核心,簡單來説,是一個 IoC 容器,用於管理 Bean。

在 Spring 中,有兩種基本類型的容器:Bean 工廠和 Application Context。前者提供基本功能,此處將介紹;後者是前者的超集,並且被廣泛使用。

ApplicationContextorg.springframework.context 包中的一個接口,並且它有多個實現,其中 ClassPathXmlApplicationContext 就是其中之一。

在本文中,我們將重點介紹 ClassPathXmlApplicationContext 提供的有用功能。

2. 基本用法

This section covers the basic usage of the library.

Installation

To install the library, use the following command:

npm install your-library-name

Getting Started

  1. Import the library into your project.
  2. Create an instance of the library.
  3. Call the library's methods to perform operations.

Example

// Import the library
const yourLibrary = require('your-library-name');

// Create an instance
const instance = new yourLibrary();

// Call a method
const result = instance.doSomething('some input');

console.log(result);

Common Methods

  • doSomething(input): Performs a specific operation.
  • anotherMethod(param1, param2): Another useful function.
  • reset(): Resets the library to its initial state.

2.1. 初始化容器和管理 Bean

<em classPathXmlApplicationContext</em> 可以從 classpath 加載 XML 配置文件並管理其中的 Bean:

我們有一個 <em Student</em> 類:

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

    // standard constructors, getters and setters
}

我們配置了一個 Student Bean 在 classpathxmlapplicationcontext-example.xml 中,並將其添加到 classpath 中:

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

現在我們可以使用 ClassPathXmlApplicationContext 類加載 XML 配置文件並獲取 Student Bean:

@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. 多個XML配置

有時,我們需要使用多個XML配置來初始化Spring容器。在這種情況下,只需在構造ApplicationContext 時添加多個配置位置:

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

3. 附加功能

3.1. 以優雅的方式關閉 Spring IoC 容器

當我們在 Web 應用程序中使用 Spring IoC 容器時,Spring 的基於 Web 的 <em >ApplicationContext</em> 實現會在應用程序關閉時優雅地關閉容器。但是,如果我們在非 Web 環境中使用它,例如獨立桌面應用程序,則必須手動向 JVM 註冊一個 shutdown hook,以確保 Spring IoC 容器以優雅的方式關閉並調用 destroy 方法以釋放資源。

讓我們為 <em >Student</em> 類添加一個 <em >destroy()</em> 方法:

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

我們現在可以將此方法配置為 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>

我們現在將註冊一個 shutdown hook:

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

當我們運行測試方法時,我們可以看到 destroy() 方法被調用。

3.2. 使用 MessageSource 進行國際化

<em >ApplicationContext</em > 接口繼承了 <em >MessageSource</em > 接口,因此提供國際化功能。

<em >ApplicationContext</em > 容器會在初始化時自動搜索 <em >MessageSource</em > 類型的 Bean,並且該 Bean 的名稱必須為 <em >messageSource</em >

以下是一個使用 <em >MessageSource</em > 實現不同語言的示例:

首先,將 <em >dialog</em > 目錄添加到 Classpath 中,並在該目錄下添加兩個文件:<em >dialog_en.properties</em ><em >dialog_zh_CN.properties</em >

<em >dialog_en.properties</em >

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

dialog_zh_CN.properties:

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

配置 messageSource Bean 在 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>

然後,我們使用 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. 對 ApplicationContext 的引用

有時我們需要在由它管理 Bean 內部獲取 ApplicationContext 的引用,可以使用 ApplicationContextAware@Autowired 來實現。 讓我們看看如何使用 ApplicationContextAware

我們有一個 Course 類,其中包含一個名稱:

public class Course {

    private String name;

    // standard constructors, getters and setters
}

我們有一個 Teacher 類,它根據容器中的 Bean 組裝課程:

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
}

讓我們配置 course Bean 和 teacher Bean 在 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>

然後 – 測試 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"));
}

除了實現 ApplicationContextAware 接口,使用 @Autowired 註解也有相同的效果。

讓我們將 Teacher 類修改為如下所示:

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
}

然後運行該測試,我們可以看到結果相同。

5. 結論

<em>ApplicationContext</em> 是一個比 <em>BeanFactory</em> 更具有企業級功能的 Spring 容器,<em>ClassPathXmlApplicationContext</em> 是其最常用的實現之一。

因此,在本文中,我們介紹了 <em>ClassPathXmlApplicationContext</em> 的幾個方面,包括其基本用法、其 shutdown 註冊功能、其國際化功能以及獲取其引用。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.