Springフレームワークが提供するDI(Dependency Injection)を理解するためのサンプルプログラムを作りました。
『Spring3入門』の 第2章 SpringのDI を参考にしています。初版の第一刷を買ったせいか、それじゃ動かないだろ、というサンプルソースもあるが許容範囲内。Java分かるけどSpring初めての人には為になる印象です。
Spring3入門 ――Javaフレームワーク・より良い設計とアーキテクチャ
- 作者: 長谷川裕一,大野渉,土岐孝平
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/02
- メディア: 大型本
- 購入: 8人 クリック: 115回
- この商品を含むブログ (15件) を見る
JavaSE1.5以上のバージョンでの実開発経験が無い身にとって衝撃的だったのは、DAOを呼び出す時に実装クラスをnewする必要が無いところ。
しかもDAOは呼び出しの都度Springがnewするのではなく、Singletonのインスタンスとして取得できる(つまりSpringからinjectされる)。
DAOをSingletonにする理由は明確でないが、都度newしないのでパフォーマンス向上は期待できると思われる。
※誤解の無いように言うと、都度newされた(Singletonでない)インスタンスとして取得することも可能。
また、ビジネスロジックの開発者がDAOの実装クラスをnewする必要なくインスタンスを取得できるので、DAOの呼び出し側(ビジネスロジック層)にDAOの実装クラス名は一切出てこない。
これは本当に気持ちが良い。インタフェースによるプログラムが可能になったのだと実感が沸く。
JUnitのテストコードの書き方に若干コツが必要なので、サンプルプログラムのソースコードをダウンロードできるようにしておきます。
20121228_SpringTest.zip
Eclipseで実行する場合は、一旦Eclipseのプロジェクトに変換してからインポートするのが楽です。
c:\SpringTest>mvn eclipse:eclipse [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building SpringTest 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-eclipse-plugin:2.8:eclipse (default-cli) @ SpringTest >>> [INFO] [INFO] <<< maven-eclipse-plugin:2.8:eclipse (default-cli) @ SpringTest <<< [INFO] [INFO] --- maven-eclipse-plugin:2.8:eclipse (default-cli) @ SpringTest --- [INFO] Using Eclipse Workspace: null [INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER [INFO] Not writing settings - defaults suffice [INFO] Wrote Eclipse project for "SpringTest" to c:\SpringTest. [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.809s [INFO] Finished at: Fri Dec 28 23:15:19 JST 2012 [INFO] Final Memory: 9M/109M [INFO] ------------------------------------------------------------------------ c:\SpringTest>
コマンドラインでMavenから起動したJUnitのテスト結果も参考までに載せておきます。
c:\SpringTest>mvn test [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building SpringTest 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ SpringTest --- [WARNING] Using platform encoding (MS932 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ SpringTest --- [WARNING] File encoding has not been set, using platform encoding MS932, i.e. build is platform dependent! [INFO] Compiling 6 source files to c:\SpringTest\target\classes [INFO] [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ SpringTest --- [WARNING] Using platform encoding (MS932 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ SpringTest --- [WARNING] File encoding has not been set, using platform encoding MS932, i.e. build is platform dependent! [INFO] Compiling 1 source file to c:\SpringTest\target\test-classes [INFO] [INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ SpringTest --- [INFO] Surefire report directory: c:\SpringTest\target\surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running sample.di.business.service.ProductServiceTest 12 28, 2012 12:25:26 午前 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners 情報: @TestExecutionListeners is not present for class [class sample.di.business.service.ProductServiceTest]: using defaults. 12 28, 2012 12:25:26 午前 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 情報: Loading XML bean definitions from class path resource [applicationContext.xml] 12 28, 2012 12:25:27 午前 org.springframework.context.support.AbstractApplicationContext prepareRefresh 情報: Refreshing org.springframework.context.support.GenericApplicationContext@15b96350: display name [org.springframework.context.support.GenericApplicationContext@15b96350]; startup date [Fri Dec 28 00:25:27 JST 2012]; root of context hierarchy 12 28, 2012 12:25:27 午前 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory 情報: Bean factory for application context [org.springframework.context.support.GenericApplicationContext@15b96350]: org.springframework.beans.factory.support.DefaultListableBeanFactory@a7393a2 12 28, 2012 12:25:27 午前 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 情報: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@a7393a2: defining beans org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,ProductService,productDaoImpl]; root of factory hierarchy Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.619 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.630s [INFO] Finished at: Fri Dec 28 00:25:27 JST 2012 [INFO] Final Memory: 14M/110M [INFO] ------------------------------------------------------------------------ c:\SpringTest>