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で利用可能]です。