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