spring framework を使ったデスクトップアプリ(standalone app)で context から getBean でオブジェクトを取得する。@Autowired による紐付け

公開日: : SpringFramework ,

先日 spring framework を使ったデスクトップアプリ(standalone app)で context から getBean でオブジェクトを取得する をアップしました。
この記事ではインスタンスの紐付けを applicationContext.xml 内で bean タグを使って行っていました。
ですが、このやり方は古い!ということで、@Autowired アノテーションと @Component アノテーションで行うようにプログラムを修正しました。
検証プログラムは Github に登録してあります。

Financial injection

目次

1. 動作環境

1-1. Java

Java のバージョンは次の通りです。

$ java -version
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

ですが、いろいろ都合があって、pom.xml にはコンパイラのバージョンを 1.6 で定義しています。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.0</version>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
    <encoding>UTF-8</encoding>
  </configuration>
</plugin>

1-2. Maven

この検証プログラムは Maven を使ってビルドしています。 プログラム作成時に使用した Maven のバージョンは次の通りです。

$ mvn -v
Apache Maven 3.0.4 (r1232337; 2012-01-17 17:44:56+0900)
Maven home: C:\Users\xxx\maven-3.0.4
Java version: 1.7.0_11, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_11\jre
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

1-3. Spring

pom.xml を見ればそこにバージョンは書いてありますが。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>3.2.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>3.2.6.RELEASE</version>
</dependency>

2. applicationContext.xml の変更について

Spring の設定ファイルである applicationContext.xml は次のように変更しました。

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="  
           http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context classpath:/org/springframework/context/config/spring-context-3.0.xsd">

  <!-- net.tomoyamkung 以下のパッケージをスキャン対象とする -->
  <context:component-scan base-package="net.tomoyamkung" />
  
  <!-- クラスにアノテーションを設定してクラスの紐付けを指定することもできるが、↓のように設定ファイルで定義することもできる -->
  <!--
  <bean id="hogeModel" class="net.tomoyamkung.model.HogeModelImpl" />
  -->

</beans>

本プロジェクトのクラスは net.tomoyamkung パッケージ以下に3クラスあります。
これらクラスを Spring の管理下におきインスタンス生成をお任せするので、component-scan で指定します。

3. プログラムの変更について

検証プログラムは次の3本です。

  • src/main/java/net/tomoyamkung/App.java
  • src/main/java/net/tomoyamkung/model/HogeModel.java
  • src/main/java/net/tomoyamkung/model/HogeModelImpl.java

それぞれのプログラムのソースコードを載せておきます。
コメントを残してあるので、インスタンスの紐付けが分かると思います。

3-1. App.java

/**
 * 動作確認用の実行クラス。
 * 
 * @author tomoyamkung
 *
 */
@Component
public class App {
  
  /**
   * Spring の設定ファイル "applicationContext.xml" のパス。
   * 
   * クラスパス上に applicationContext.xml がある場合、このような書き方で参照できる。
   */
  private static final String SPRING_CONFIG_FILE = "classpath:applicationContext.xml";

  /**
   * <code>HogeModel</code> クラスのインスタンス。
   * 
   * <code>@Autowired</code> でインスタンスが設定される。
   */
  @Autowired
  private HogeModel hoge;

  /**
   * 動作確認用の実行メソッド。
   * 
   * @param args
   */
  public static void main(String[] args) {
    AbstractApplicationContext context = new ClassPathXmlApplicationContext(SPRING_CONFIG_FILE);

    // App クラスの型を指定してインスタンスを取得する
    App app = context.getBean(App.class);
    
    // @Autowired により自動で HogeModel を実装した HogeModelImpl クラスのインスタンスが設定される
    app.hoge.printLog("Hello, spring-standalone-sample!!");
    
    context.close(); // close しないと警告が出る
  }
}

3-2. HogeModel.java

このクラスはインタフェースなので変更点はありません。

/**
 * Context から取得するサンプル Bean のインタフェース。
 * 
 * @author tomoyamkung
 *
 */
public interface HogeModel {
  
  /**
   * ログに出力する。
   * 
   * @param message
   */
  void printLog(String message);
}

3-3. HogeModelImpl.java

/**
 * Context から取得するサンプル Bean クラス。
 * 
 * @author tomoyamkung
 *
 */
@Service // HogeModel を実装するクラスは本クラスだけなので @Service アノテーションの引数で論理名を指定しなくてもよい
public class HogeModelImpl implements HogeModel {
  
  private static final Logger log = Logger.getLogger(HogeModelImpl.class);

  /* (non-Javadoc)
   * @see net.tomoyamkung.model.HogeModel#printLog(java.lang.String)
   */
  @Override
  public void printLog(String message) {
    log.debug(message);
    
  }

}

4. HogeModel インタフェースについて

App クラスがインタフェースを実装せずに @Component アノテーションを付与するだけで ApplicationContext からインスタンスを取得できています。
これは、インタフェースを実装しなくても、インスタンス生成を Spring に任せられるということです。

なので、HogeModelImpl クラスも HogeModel を実装せずにインスタンスを取得できます。
必要ないのならインタフェースを定義しなくて OK です。面倒くさいだけですから。

では、どのような場合にインタフェースが必要なのかというと、ありがちなのは次のケースでしょうか。

  1. そのインタフェースを実装する具象クラスが複数存在する場合
  2. 自分がコーディング担当ではなく、開発メンバーが担当する場合
  3. JUnit などの単体テストを実行する場合に処理を切り分けたい場合

5. 動作方法

  1. 本プロジェクトを clone する、もしくはダウンロードする
  2. プロジェクトに移動してビルドする
  3. App.java を実行する

ビルドのコマンドは次の通りです。

$ mvn clean package

App.java を実行すると、次のような内容がコンソールに出力されます。

2014-01-26 00:53:06,138 DEBUG net.tomoyamkung.model.HogeModelImpl.printLog:22 - Hello, spring-standalone-sample!!

6. まとめ

Spring は 1.x 系のものを遥か昔に触ったことがあります。
そのとき bean の管理をすべて applicationContext.xml で行っていたので「面倒くさいなぁ」と思ったものですが、アノテーションだけで管理できるようになっていたんですね。。。

今回の変更をバージョン 0.3 としてタグ付けしました。

よかったら参考にしてみてください。

7. その他の Spring に関する記事

Spring に関する記事は次の通りです。
気になる記事があったらぜひチェックしてみてください!

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch-cron_5578829409

Spring の Scheduled アノテーションを使った cron サンプル

Spring の @Scheduled アノテーションを使った cron サンプルプログラムを作成し

記事を読む

icatch-dbcp-219581864

Spring の DataSource に DBCP を使用する

Spring の DataSource に DBCP を設定してみたのでメモしておきます。 目

記事を読む

icatch-log_5578829409

SpringJDBC が発行する SQL をログに出力する

SpringJDBC が発行する SQL を確認する必要があったので Apache log4j 1.

記事を読む

icatch-java

Spring の設定ファイル applicationContext.xml の内容をプロパティファイルに切り出す

Spring の設定ファイルである applicationContext.xml に DataSou

記事を読む

icatch-spring

spring framework を使ったデスクトップアプリ(standalone app)で context から getBean でオブジェクトを取得する

Java では珍しく Web ではなくデスクトップアプリの開発があり、そのプロジェクトで Sprin

記事を読む

icatch-mysql_5578829409

MySQL の JDBC ドライバで設定しておきたい rewriteBatchedStatements プロパティ

データベースに MySQL を使った Java アプリのバッチ更新処理について非常に勉強になることが

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


1 × = 八

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑