← 解説「XML・アノテーション・JavaConfig」に戻る
サンプルコードで身につける: XML・アノテーション・JavaConfig
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1出発点: 素の Java で手で配線する
を使わずに、2つのを の中で作ってつなぐ例です。とは「どのクラスを作り、誰に誰を渡すか」のことで、ここでは new の2行がそれに当たります。以降の3通りは、この2行の情報をどこに書くかの違いです。
Java
2XML で配線する(1.0 より前からある書き方)
配線を に書いた版です。bean 要素の class がどのクラスを作るか、constructor-arg の ref が誰を渡すかを表し、業務クラスには Spring の がありません。この XML は 7.0.9 と 25 で、警告なしに動きました。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="messageRepository" class="demo.plain.MessageRepository"/><bean id="greetingService" class="demo.plain.GreetingService"><constructor-arg ref="messageRepository"/></bean></beans>
import demo.plain.GreetingService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class XmlMain {
public static void main(String[] args) {
// クラスパス上の beans.xml を読んでコンテナを作る
try (var ctx = new ClassPathXmlApplicationContext("beans.xml")) {
System.out.println("[xml] " + ctx.getBean(GreetingService.class).greet());
System.out.println("[xml] beans = " + String.join(", ", ctx.getBeanDefinitionNames()));
}
}
}
3アノテーションで配線する(2.5 の書き方)
クラスに を付け、に を付けた版です。起動側は名を渡すだけで、Spring がその下のクラスを探して組み立てるので、配線をまとめて書いた場所はどこにもありません。現行の版では、コンストラクタが1つなら @Autowired は省略できます。
// demo/anno/MessageRepository.java
@Component
public class MessageRepository {
public String find() { return "hello"; }
}
// demo/anno/GreetingService.java
@Component
public class GreetingService {
private final MessageRepository repository;
@Autowired
public GreetingService(MessageRepository repository) {
this.repository = repository;
}
// greet() は省略
}
// demo/AnnotationMain.java
public class AnnotationMain {
public static void main(String[] args) {
// "demo.anno" パッケージの下を探してもらう
try (var ctx = new AnnotationConfigApplicationContext("demo.anno")) {
System.out.println("[annotation] " + ctx.getBean(GreetingService.class).greet());
}
}
}
// import は org.springframework.stereotype.Component と
// org.springframework.beans.factory.annotation.Autowired。
// 業務クラスが Spring の型に依存するようになった点が XML との違い
43通りを動かした出力を並べる
同じ2つの部品を3通りで配線し、Spring Framework 7.0.9 と JDK 25 で動かした出力です(@ の後ろの数値は実行のたびに変わります)。XML では登録された は自分で書いた2つだけですが、残りの2つでは internal を含む名前の Bean が4つ先に並びます。を処理する役を、が自分で登録しているためです。
$ java -cp 'out:lib/*' demo.XmlMain[xml] hello (repository@1335505684)[xml] beans = messageRepository, greetingService$ java -cp 'out:lib/*' demo.AnnotationMain[annotation] hello (repository@282821294)[annotation] beans = org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, greetingService, messageRepository$ java -cp 'out:lib/*' demo.JavaConfigMain[javaconfig] hello (repository@1926343982)[javaconfig] beans = org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, appConfig, messageRepository, greetingService
53通りの比較表
3つの書き方を、確かめられた版と配線の情報の置き場所で並べました(日付は各版の告知のもの)。XML による定義は 1.0 より前からあり、0.9(2003年6月)の changelog に既に出てきます。アノテーションだけが業務クラスに Spring の import を持ち込み、 は別プロジェクトとして存在したものが 3.0 で本体に入りました。
書き方 | 確かめた版 | 告知の日付 | 配線の情報がある場所 | 業務クラスの Spring への依存---------------+------------+-------------+-------------------------------+-----------------------------XML | 1.0 に既出 | 2004-03-24 | beans.xml | なしアノテーション | 2.5 | 2007-11-19 | それぞれのクラスに付けた印 | ありJavaConfig | 3.0 | 2009-12-16 | @Configuration を付けたクラス | なし