SpringClassPathXmlApplicationContextの概要
1. 概要
Spring Frameworkコアは、簡単に言えば、Beanの管理に使用されるIoCコンテナーです。
Springには、BeanFactoryとApplicationContextの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
}
StudentBeanをclasspathxmlapplicationcontext-example.xmlで構成し、クラスパスに追加します。
<beans ...>
<bean id="student" class="com.baeldung.applicationcontext.Student">
<property name="no" value="15"/>
<property name="name" value="Tom"/>
</bean>
</beans>
これで、 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. 複数のXML構成
Springコンテナを初期化するためにいくつかのXML構成を使用したい場合があります。 その場合、 ApplicationContext を構築するときに、いくつかの構成場所を追加する必要があります。
ApplicationContext context
= new ClassPathXmlApplicationContext("ctx.xml", "ctx2.xml");
3. 追加機能
3.1. SpringIoCコンテナを正常にシャットダウンします
WebアプリケーションでSpringIoCコンテナーを使用する場合、SpringのWebベースの ApplicationContext 実装は、アプリケーションのシャットダウン時にコンテナーを正常にシャットダウンしますが、次のような非Web環境で使用する場合スタンドアロンのデスクトップアプリケーションの場合、Spring IoCコンテナが正常にシャットダウンされ、destroyメソッドを呼び出してリソースを解放するように、自分でシャットダウンフックをJVMに登録する必要があります。
destroy()メソッドをStudentクラスに追加しましょう。
public void destroy() {
System.out.println("Student(no: " + no + ") is destroyed");
}
これで、このメソッドを 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>
次に、シャットダウンフックを登録します。
@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 ディレクトリをクラスパスに追加し、2つのファイルdialog_en.propertiesとdialog_zh_CN.propertiesを追加しましょう。
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でmessageSourceBeanを構成します。
<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
}
courseBeanとteacherBeanを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>
次に–コースプロパティの注入をテストします。
@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 の基本的な使用法、シャットダウン登録機能、国際化機能、参照の取得など、いくつかの側面を紹介しました。
いつものように、この例の完全なソースコードは、GitHubでから入手できます。