Spring ClassPathXmlApplicationContextの紹介

1概要

Spring Frameworkのコアは、簡単に言えば、Beanの管理に使用されるIoCコンテナです。

Springには、Beanファクトリとアプリケーションコンテキストという2つの基本タイプのコンテナがあります。前者は基本的な機能性を提供し、それらは ここ を導入します。後者は前者のスーパーセットであり、最も広く使用されています。

ApplicationContext は、 org.springframework.context パッケージのインターフェースであり、いくつかの実装があり、 ClassPathXmlApplicationContext はそのうちの1つです。

この記事では、 ClassPathXmlApplicationContext によって提供される便利な機能に焦点を当てます。

** 2基本的な使い方

2.1. コンテナの初期化とBeanの管理

ClassPathXmlApplicationContext はクラスパスからXML設定を読み込み、そのBeanを管理できます。

Student クラスがあります。

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

   //standard constructors, getters and setters
}

classpathxmlapplicationcontext-example.xml Student Beanを構成し、それをクラスパスに追加します。

<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設定

Springコンテナを初期化するためにいくつかのXML設定を使いたいことがあります。その場合は、 ApplicationContext を構築するときに単純にいくつかの構成場所を追加する必要があります。

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

3追加機能

3.1. Spring IoCコンテナを安全にシャットダウンする

WebアプリケーションでSpring IoCコンテナを使用する場合、アプリケーションのシャットダウン時にSpringのWebベースの ApplicationContext 実装はコンテナを適切にシャットダウンしますが、スタンドアロンデスクトップアプリケーションなどの非Web環境で使用する場合は、 Spring IoCコンテナが適切にシャットダウンされ、destroyメソッドを呼び出してリソースを解放することを確認するために、自分自身でシャットダウンフックをJVMに登録する必要があります。

destroy() メソッドを Student クラスに追加しましょう。

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

これで、このメソッドを student Beanの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>

シャットダウンフックを登録します。

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

テストメソッドを実行すると、 destroy() メソッドが呼び出されているのがわかります。

3.2. MessageSource による国際化

ApplicationContext インターフェースは MessageSource インターフェースを拡張するため、国際化機能を提供します。

ApplicationContext コンテナは、初期化時に MessageSource Beanを自動的に検索します。このBeanの名前は messageSource にする必要があります。

これは MessageSource でさまざまな言語を使用する例です。

まず、 dialog ディレクトリをクラスパスに追加し、ダイアログディレクトリに dialog en.properties dialog zh CN.properties__の2つのファイルを追加しましょう。

dialog en.properties__:

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

dialog zh CN.properties :

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

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>

それでは、 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
}

コンテナのBeanに従ってコースを組み立てる Teacher クラスがあります。

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
}

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>

それから - 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結論

ApplicationContext は、 BeanFactory と比較して、より企業固有の機能を備えたSpringコンテナです。また、 ClassPathXmlApplicationContext は、その最も一般的に使用されている実装の1つです。

この記事では、 ClassPathXmlApplicationContext の基本的な使用方法、シャットダウン登録機能、国際化機能、および参照の取得など、いくつかの側面について説明しました。

いつものように、この例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-core/src/test/java/com/baeldung/applicationcontext/[GitHubで利用可能]です。