Spring3.1概要x di
-
Upload
hasegawa-yuichi -
Category
Technology
-
view
7.938 -
download
0
description
Transcript of Spring3.1概要x di
Spring概要とDI for Beginner
2012/2/13
SpringFramework概要 SpringFrameworkからSpringへ!?
Spring • Spring Framework
‒ ロッド・ジョンソン氏(SpringSource[旧社名:Interface21])が中心に開発
‒ Java/JEEアプリケーション開発用フレームワーク • DIxAOPコンテナ
‒ ASL(Apache Software Licence) Ver2.0に基づいたオープンソース
3
springsource.org
Springの年譜 • 2002年11月 書籍:Expert One-on-One J2EE • 2004年3月 Spring 1.0 • 2004年9月 Spring 1.1 • 2005年5月 Spring 1.2 • 2006年10月 Spring 2.0 • 2007年11月 Spring2.5 • 2009年12月 Spring3.0 • 2011年12月 Spring3.1
‒ Java7, Spring Cache... • 201x年 Spring3.2
‒ Hibernate4 FullSupport...
5
Springの主なプロジェクト • Spring AMQP • Spring Android • Spring Batch • Spring BlazeDS • Spring Data • Spring Framework • Spring Gemfire • Spring Integration
6
• Spring Mobile • Spring .NET • Spring Roo • Spring Security • Spring Security OAuth
• Spring Social • Spring Web Flow • Spring Web Services
SpringSource 何があるのか、どこへ行くのか!?
springsource.com
SpringSourceの年譜
開発-実行-管理
Spring Roo • コマンドラインを利用してソースを自動生成するツール
‒ 生産性の向上及び仕様変更や機能追加にも耐えうる継続的な開発 ‒ Java界隈においてメジャーなフレームワークを利用 ‒ 自動生成した後もモデルクラスの変更に対して、ビューやコントロー
ラクラスが自動で再作成される
11
STS • SpringSource Tool Suite
‒ EclipseベースのSpringアプリケーション開発環境 ‒ 各種サーバへのデプロイ管理
VMforce • Force.comで実行可能なSpringアプリケーションを Javaで開発、実行、実行するためのサービス
• Force.com ‒ リレーショナルデータベース、全文検索エンジン、レポートや分析、ユーザやアイデンティティ情報の管理...
vFabric • VMwareの今後の方向性を占うソリューション ‒ クラウド向けのアプリケーション基盤(ミドルウェア)
vFabric
VMware
Spring Application
vFabric • VMWare が提供する Java アプリケーションプラットホーム
‒ AP サーバーやデータベースやメッセージキューなどのソフトウェアを1セットで提供する
• VMware vFabric Cloud Application Platform ‒ vSphere のメモリ管理機能を利用したコンピュータリソースの有効活
用 ‒ vCenter によるアプリケーションの監視 ‒ 仮想マシンの数に応じた価格体系を提供
tc Server • エンタープライズ向けにカスタマイズされた Tomcat ‒ 開発者に馴染みの Tomcat互換 ‒ Springを利用して作成したアプリケーションを実 行するのに適した環境
• Tomcat + α ‒ Webベースの管理UI ‒ アプリケーションの設定とデプロイ管理 ‒ パフォーマンスのモニターおよび状態の診断
ERS(Enterprise Ready Server) • Web サーバーとロードバランスの機能を提供
‒ Apache HTTP Server を使用 ‒ Apache と比較して最大 100% のパフォーマンスアップ
• 迅速にバグフィックスするサポートを提供 ‒ Apache HTTP Server のサポートを提供していた Covalent 社を SpringSource が買収
ERS
tc Server
tc Server
RabbitMQ • AMQP(Advanced Message Queuing Protocol) を実装したメッセージキュー
• 多彩なメッセージングのパターンに対応 ‒ point-to-point, publishsubscribe,routing...
• 多彩なプロトコル、言語(クライアント側)に対応
RabbitMQ tc Server Spring Apprication
Cloud時代のスケール メッセージBus
GemFire • メモリーベースの分散型のデータ管理プラットホーム(永続化も可能) ‒ Key-Value ストア ・マシンを動的に追加可能 ‒ 非同期のイベント通知
GemFire tc Server Spring Apprication
Cloud時代のスケール データストレージ
Hyperic • tc Serverの管理・監視・計測
‒ 他のミドルウェアや OS リソースも監視できる • 管理
‒ ランタイムインスタンスの起動・停止 ‒ JVM オプション・ JDBC データソースなどの設定 ‒ Web アプリケーションのデプロイ
• 監視 ‒ リソースの閲覧・監視・コントロール ‒ デッドロックの検知 ‒ ガベージコレクションの時間 ‒ JDBC データソースの監視
• 計測 ‒ instrumented 版の Spring Framework を利用し、 bean のメソッドの処理時間などを表示
これから!? • エンタープライズ開発
‒ Spring Framework + その他のプロダクト • プライベートCloud
‒ vFablic + vSphere • PaaS
‒ VMforce ‒ CloudFoundary
DIコンテナ システム開発と部品化…
ソフトウェアを部品化したい • 電気製品みたいなことがしたい!
‒ 部品化 = インタフェース接続
部品化とインタフェース • インタフェースが穴の方 • 部品(コンポーネント)化するときに、インタフェースをもつのは「偉い方」
ステレオ スピーカ
部品 部品
インタフェースとレイヤ,パッケージ • 変更単位や開発単位に適宜導入する
‒ レイヤ • パソコン, ディスプレイ, キーボード...
‒ パッケージ(コンポーネント) • パソコンの中のCPU, メモリ, HDD...
25
プレゼン テーション
ビジネス ロジック
データベース アクセス
RDB
ブラウザ
表示の仕組み 永続化の仕組み 業務の仕組み
インタフェースで分散開発 • 分割単位毎(レイヤ,パッケージ,コンポーネントなど)に、インタフェースを利用して、開発チームを分ける
26
R Q
疑似
疑似 Q
QImpl
R
Q QImpl
インタフェース導入の難しさ • インタフェースの実装を、インタフェースを利用するクラスが生成(インスタンス化)してはいけない
27
R QImpl (Qの実装)
Q
②利用
①生成
public class R { ・・・ Q q = new QImpl(); // ダメ q.methodA(); String m = q.methodB(); ・・・
インタフェース導入とFactory • インタフェースの実装を生成(インスタンス化)するFactory(FactoryMethod)を用意(自作)することで解決する
28
R QImpl (Qの実装)
Q
③利用
Factory
①生成の 要求
②生成
public class R { ・・・ Q q = (Q)Factory.create(KEY); q.methodA(); String m = q.methodB(); ・・・
KEY=QImpl
Factoryの例
29
public static Object create(String keyName) { // keyNameを元にファイルを読み込んで、生成するクラス名を取得する Class<?> clazz = Class.forName(createName); Object obj = clazz.newInstance(); return obj; }
R QImpl (Qの実装)
Q
③利用
Factory
①生成の 要求
②生成
KEY=QImpl
Factoryにもうひと工夫 • Webアプリケーションは、マルチスレッドで動作する • マルチスレッド配下の(ステートレスな)処理は、スレッド単にイ
ンスタンス化するのではなく、システム内に1つあれば良い
30
:FindAction
:Employee ServiceImpl
:Employee ServiceImpl
:Employee ServiceImpl
:FindAction :Employee ServiceImpl
マルチスレッド
マルチスレッド
インスタンス化
インスタンス化
FactoryをSingleton対応にする • 1度インスタンス化されたクラスは、2回目のインスタンス化のリクエストに対して、同じインスタンスを返してしまえば良い ‒ クラスのSingleton化が不要
31
private EmployeeServiceImpl empService = null; ・・・ public static Object create(String keyName) { // keyNameが同じだったら、リターン return (Object)EmpService; // 初めてのkeyNameだったら、シンクロナイズして以下を実行 Class<?> clazz = Class.forName(createName);
Object obj = clazz.newInstance(); return obj; }
はしょってる ので注意
DIコンテナを利用する! • Factoryではなく、DIコンテナを使用することでインタフェースが容易に扱える
• しかも、Factoryのようにソースコードに現れない
32
DIコンテナ ①生成 ②セット
R QImpl (Qの実装)
Q
public class R { @Autowired private Q q; ・・・ q.methodA(); String m = q.methodB(); ・・・
DIコンテナ導入後
ようやくDIの登場! • DI(Dependency Injection)
‒ 依存性の注入 • インタフェースの導入が楽
33
EmpServiceImpl
DIコンテナ
①生成
②セット (依存性の注入)
③利用 DB2EmpDao
EmpDao
Singletonへの対応 • 一般的に利用されているDIxAOPコンテナであれば、インスタンスをSingletonとして生成するか、リクエスト毎にインスタンス化のどちらかを選ぶことができる ‒ Spring,Seasar2 ...etc
34
SpringでおこなうDI • アノテーションの利用
‒ Spring2.x系以降、アノテーションの利用が増えている(大規模開発や大手SI便だでは定義ファイルの利用が多い)
‒ メリット:定義ファイルの管理が不要 ‒ デメリット:プログラマにアノテーションを意識
• 定義ファイルの利用 ‒ Springの基本 ‒ メリット:プログラマにSpringを意識させない ‒ デメリット:定義ファイルの管理
35
INJECTION! アノテーションを使った
アノテーションを利用したDI • インジェクションの設定(自動検出)
‒ @Autowired • Beanの設定
‒ @Component
37
@Component class DaoImpl implements Dao { ... }
class Service { @Autowired private Dao dao; ... }
Injection
Dao
主なインジェクションの設定 • @Autowired
‒ byType ‒ プロパティ,コンストラクタ,メソッドで有効
‒ 複数のパラメータやコレクション型に対応 ‒ @Autowired(required=false)
• @Qualifier ‒ @Autowiredと組み合わせてbyName ‒ @Qualifier("hogeImpl");
38
主なBeanの設定 • @Component
‒ SpringのBeanとして扱う ‒ @Component(“任意の名前”)も可能。省略時はクラス名の先頭小文字
39
... @Component public class Hoge { ...
問題 こんなことできる?
40
public class Hoge { @Autowired private Fuga f; @Autowired private FugaFuga ff;
@Component public class FugaImpl implements Fuga { ... }
@Component public class FugaFugaImpl implements FugaFuga { ... }
public class Hoge { @Autowired public Hoge(Fuga f, FugaFuga ff) {...} @Autowired public m(Fuga f, FugaFuga ff) {...}
アノテーションでも必要。Bean定義ファイル
41
<?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 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config /> <context:component-scan base-package="sample.di.*"/>
</beans>
タグ解説 • <context:annotation-config />
– @Autowired,@Resourceを利用する場合 • <context:component-scan base-package= "パッケージ名, ・・・"/>
– @Component,@Serviceなどを利用する場合"‒ base-packageで指定したパッケージ名以下のコンポーネントを検索する
42
その他のスキーマ一覧
43
名称 スキーマ ファイル
URI 説明
utilスキーマ spring-util.xsd http://www.springframework.org/schema/util 定数定義やプロパティファイルの読み込み等のユーティリティ機能の設定を簡略化
jeeスキーマ spring-jee.xsd http://www.springframework.org/schema/jee JNDIのlookupおよび、EJBのlookupの設定を簡略化
langスキーマ spring-lang.xsd http://www.springframework.org/schema/lang スクリプト言語による設定を簡略化
aopスキーマ spring-aop.xsd http://www.springframework.org/schema/aop AOPの設定を簡略化
txスキーマ spring-tx.xsd http://www.springframework.org/schema/tx トランザクションの設定を簡略化
問題 2つあったら? • Autowireでインタフェースを実装するクラスが2つあったらどうなる?
@Component class ADaoImpl implements Dao { ... }
class Service { @Autowired private Dao dao; ... } Dao
@Component class BDaoImpl implements Dao { ... }
問題 じゃあ、Unitテストどうする?
@Component class DaoImpl implements Dao { ... }
class Service { @Autowired private Dao dao; ... } Dao
@Component class TestDaoImpl implements Dao { ... }
解答の1つ:切り替え毎に…
46
<?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 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config /> <context:component-scan base-package="sample.di.service"/> <!-- <context:component-scan base-package="sample.di.dataaccess"/> --> <context:component-scan base-package="test"/> </beans>
ワイルドカードはやめて、 コンポーネント毎に宣言する
問題 インターフェイスがない?
@Component class Dao { ... }
class Service { @Autowired private Dao dao; ... }
問題 1つもなかったら? • Autowireでインタフェースを実装するクラスがなかったらどうなるか?
class Service { @Autowired private Dao dao; ... } Dao
レイヤ毎のBeanの設定 • 全て@Componentの拡張 • @Controller
‒ プレゼン層SpringMVC用 • @Service
‒ ビジネス層Service用 ‒ トランザクション管理ができるとか噂はありました…
• @Repository ‒ データアクセス層DAO用 ‒ 例外を全てDataAccessExceptionに変換
49
... @Service public class Hoge { ...
主なBeanスコープ • @Scope
‒ @Componentと併用。Beanのスコープを決める ‒ 省略時はsingleton ‒ @Scope(“Value属性”) ‒ Value属性
• singleton・・・シングルトン • prototype・・・その都度インスタンス生成
50
... @Component @Scope(“prototype”) public class Hoge { ...
Web用のBeanスコープ • @Scope
‒ Value属性 • request・・・Servlet APIのrequestスコープ • session・・・Servlet APIのsessionスコープ
51
... @Component @Scope(“session”) public class Hoge { ...
ライフサイクル • @PostConstruct • @PreDestroy
52
public class Hoge { ... @PostConstruct public void start() {...} @PreDestroy public void stop() {...} ...
... <context:annotation-config /> ...
定義ファイルでINJECTION ここには地獄があった?
Bean定義ファイルの基本 • アノテーションを利用することにより、Bean定義ファイルの記述負荷は減った
• しかし、最低限の知識は必要 ‒ スキーマの設定 ‒ Beanの設定
• 大規模開発で、アノテーションをプログラマに書かせるのはやっぱり嫌だ! ‒ というのもある
54
Bean定義ファイル <?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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "service" class = "sample.di.service. ServiceImpl"> <property name = "dao" ref = "dao"/> </bean> <bean id = "dao" class = "sample.di.dataaccess.DaoImpl" /> </beans>
55
contextがないことに注意
主要タグの主な属性 属性 意味
id システム内で一意とするオブジェクト名。
name Bean定義ファイル内で、id以外に名前を設定したい場合に設定する別名。
空白、「,」、「;」で区切ることにより、複数の値を設定できる。 class idの実態。パッケージ名+クラス名。
56
属性 意味
name ref属性で指定したオブジェクトをインジェクションする属性の名前。「set + “name属性で指定した属性名”」のメソッドを利用する(属性名は使われないことに注意)。
ref インジェクションしたいbeanのid(beanタグのid属性で指定された名前)。
<bean>
<property>
セッタインジェクション
57
public class ServiceImpl implements Service { private Dao dao;
public void setDao(Dao dao) { this. dao = dao; } …
DaoImpl ServiceImpl Dao
Spring
setDao
定義ファイル
58
・・・ <bean id = ”service" class = ”com.starlight.business.ServiceImpl"> <property name = ”dao” ref = ”dao"/> </property> </bean>
<bean id = ”dao" class = ”com.starlight.dataaccess.DaoImpl" /> ・・・
DaoImpl ServiceImpl Dao
Spring
setDao
定義ファイル
59
・・・ <bean id = ”service" class = ”com.starlight.business.ServiceImpl" autowire="byType" /> <bean id = ”dao" class = ”com.starlight.dataaccess.DaoImpl" /> ・・・
DaoImpl ServiceImpl Dao
Spring
setDao
問題 じゃあ、これはどうなる? • クラス図を書いてみてください
・・・ <bean id="hogeService" class="sample.HogeServiceImpl"> <property name = "hogeDao" ref = "hogeDao"/> <property name = "hogehogeDao" ref = "hogehogeDao"/> </bean>
<bean id = "hogeDao" class = "sample.HogeDaoImpl" /> <bean id = "hogehogeDao" class = "sample.HogehogeDaoImpl" /> ・・・
問題 エラー?どうして? • 前の問題の続きです。エラーの原因はなんでしょう
public class HogeServiceImpl { private HogeDaoImpl hd; private HogehogeDaoImpl hhd;
... public void setHd (HogeDaoImpl hd) { this.hd = hd; }
public void setHhd(HogehogeDaoImpl hhd) { this.hhd = hhd;
} }
おまけ
サンプルを起動したいとき • Springをお試しで使う例です
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) { // 定義ファイルを読んで、コンテナを生成 ApplicationContext ctx = new ClassPathXmlApplicationContext("/sample/config/applicationContext.xml"); // コンテナからコンポーネントの取り出し ProductService productService = (ProductService) ctx.getBean("productService"); // コンポーネントの動作確認 Product product = productService.getProduct(); System.out.println(product); }
}