Intro to the Spring ClassPathXmlApplicationContext – Spring ClassPathXmlApplicationContext的介绍

最后修改: 2016年 12月 13日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The Spring Framework core is, simply put, an IoC container used to manage beans.

简单地说,Spring框架核心是一个用于管理Bean的IoC容器。

There are two basic types of containers in Spring – the Bean Factory and the Application Context. The former provides basic functionalities, which are introduced here; the latter is a superset of the former and is most widely used.

在Spring中有两种基本类型的容器–Bean Factory和Application Context。前者提供基本功能,在此介绍;后者是前者的超集,使用最为广泛。

ApplicationContext is an interface in the org.springframework.context package and it has several implementations, and the ClassPathXmlApplicationContext is one of these.

ApplicationContextorg.springframework.context包中的一个接口,它有几个实现,ClassPathXmlApplicationContext是其中一个。

In this article, we’ll focus on the useful functionalities provided by the ClassPathXmlApplicationContext.

在这篇文章中,我们将重点讨论ClassPathXmlApplicationContext所提供的有用功能。

2. Basic Usage

2.基本的使用方法

2.1. Initialize Container and Manage Beans

2.1.初始化容器和管理Bean

ClassPathXmlApplicationContext can load an XML configuration from a classpath and manage its beans:

ClassPathXmlApplicationContext可以从classpath加载一个XML配置并管理其Bean。

We have a Student class:

我们有一个Student班。

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

    // standard constructors, getters and setters
}

We configure a Student bean in classpathxmlapplicationcontext-example.xml and add it into a classpath:

我们在classpathxmlapplicationcontext-example.xml中配置一个Student bean,并将其添加到classpath中。

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

Now we can use the ClassPathXmlApplicationContext to load the XML configuration and get the Student bean:

现在我们可以使用ClassPathXmlApplicationContext来加载XML配置并获得Studentbean。

@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. Multiple XML Configurations

2.2.多种XML配置

Sometimes we want to use several XML configurations to initialize a Spring container. In that case, we simply need to add several configuration locations when constructing the ApplicationContext:

有时我们想使用几个XML配置来初始化一个Spring容器。在这种情况下,我们只需要在构造ApplicationContext时添加几个配置位置。

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

3. Additional Capabilities

3.其他能力

3.1. Shut Down the Spring IoC Container Gracefully

3.1.优雅地关闭Spring IoC容器

When we use Spring IoC container in a web application, Spring’s web-based ApplicationContext implementations will shut down the container gracefully when the application is shut down, but if we use it in a non-web environment, such as a standalone desktop application, we have to register a shutdown hook with the JVM by ourselves to make sure the Spring IoC container is shut down gracefully and calls the destroy methods to release resources.

当我们在网络应用中使用Spring IoC容器时,Spring基于网络的ApplicationContext实现会在应用关闭时优雅地关闭容器,但如果我们在非网络环境中使用,如独立的桌面应用,我们必须自己向JVM注册一个关闭钩,以确保Spring IoC容器优雅地关闭并调用destroy方法来释放资源。

Let’s add a destroy() method to the Student class:

让我们给Student类添加一个destroy()方法。

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

We can now configure this method as the student bean’s destroy method:

我们现在可以将这个方法配置为studentbean的destroy方法。

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

We’ll now register a shutdown hook:

我们现在要注册一个关机钩。

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

When we run the test method, we can see the destroy() method is called.

当我们运行测试方法时,我们可以看到destroy()方法被调用。

3.2. Internationalization With MessageSource

3.2.使用MessageSource的国际化

The ApplicationContext interface extends the MessageSource interface, therefore provides internationalization functionality.

ApplicationContext接口扩展了MessageSource接口,因此提供国际化功能。

An ApplicationContext container automatically searches for a MessageSource bean in its initialization, and the bean must be named as messageSource.

ApplicationContext容器在其初始化中自动搜索MessageSourcebean,并且该bean必须被命名为messageSource

Here is an example of using different languages with MessageSource:

下面是一个用MessageSource使用不同语言的例子。

First, let’s add a dialog directory into a classpath and add two files into the dialog directory: dialog_en.properties and dialog_zh_CN.properties.

首先,让我们在classpath中添加一个dialog目录,并在对话框目录中添加两个文件。dialog_en.propertiesdialog_zh_CN.properties

dialog_en.properties:

dialog_en.properties

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

dialog_zh_CN.properties:

dialog_zh_CN.properties

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

Configure the messageSource bean in classpathxmlapplicationcontext-internationalization.xml:

classpathxmlapplicationcontext-internationalization.xml中配置messageSource bean。

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

Then, let’s get different languages’ dialog words with MessageSource:

然后,让我们用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. A Reference to the ApplicationContext

4.对ApplicationContext的引用

Sometimes we need to obtain the reference of ApplicationContext inside the beans managed by it, we can use ApplicationContextAware or @Autowired to do this. Let’s see how using ApplicationContextAware works:

有时我们需要在其管理的Bean中获取ApplicationContext的引用,我们可以使用ApplicationContextAware@Autowired来实现。让我们看看使用ApplicationContextAware如何工作。

We have a Course class with a name:

我们有一个有名字的Course类。

public class Course {

    private String name;

    // standard constructors, getters and setters
}

We have a Teacher class which assembles its courses according to the container’s beans:

我们有一个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
}

Let’s configure the course bean and the teacher bean in classpathxmlapplicationcontext-example.xml:

让我们在classpathxmlapplicationcontext-example.xml中配置course bean和teacher bean。

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

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

Then – test the injection of the courses property:

然后–测试注入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"));
}

Besides implementing the ApplicationContextAware interface, using the @Autowired annotation has the same effect.

除了实现ApplicationContextAware接口,使用@Autowired注解也有同样的效果。

Let’s change the Teacher class to this:

让我们把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
}

Then run that test, we can see the result is the same.

然后运行该测试,我们可以看到结果是一样的。

5. Conclusion

5.结论

ApplicationContext is a Spring container with more enterprise-specific functionalities in comparison with BeanFactory, and the ClassPathXmlApplicationContext is one of its most commonly used implementation.

ApplicationContext是一个Spring容器,与BeanFactory相比具有更多的企业特定功能,而ClassPathXmlApplicationContext是其最常用的实现之一。

So in this article, we introduced several aspects of the ClassPathXmlApplicationContext, including its basic usage, its shutdown registration functionality, its internationalization functionality and obtaining of its reference.

所以在这篇文章中,我们介绍了ClassPathXmlApplicationContext的几个方面,包括它的基本用法、它的关闭注册功能、它的国际化功能和获得它的引用。

As always, the complete source code for the example is available over on GitHub.

一如既往,该示例的完整源代码可在GitHub上获得over