今さら人には聞けない 入門 - seasar foundation · diコンテナを利用する方法...

26
© The Seasar Foundation and the others 2006. all rights reserved. 1 Seasar Conference Seasar Conference 2006 Autumn 2006 Autumn Seasar Conference Seasar Conference 2006 Autumn 2006 Autumn 今さら人には聞けない 今さら人には聞けない AOP AOP 入門 入門 2006.11.12 エスエムジー株式会社 小森 裕介([email protected]

Upload: others

Post on 28-May-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.1

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

今さら人には聞けない今さら人には聞けないAOPAOP入門入門

2006.11.12エスエムジー株式会社

小森 裕介([email protected]

Page 2: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.2

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

はじめにはじめに

そんなことはない!・・・と思います

でも、AOPが開発の中で一般的になりつつあるのもまた事実・・・

そろそろ『知らない』って言えなくなってきたアナタに、AOPの基礎を50分で伝授します!

「えっ!?AOPって、もう『今さら聞けない』の?」

Page 3: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.3

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

はじめまして!はじめまして!

•• 名前:名前:小森 裕介

•• BlogBlog::http://d.hatena.ne.jp/y-komori/•• 所属:所属:エスエムジー株式会社(http://www.smg.co.jp)

•• 主な仕事:主な仕事:– Javaによる集中監視制御システム設計・開発

– Webアプリケーションシステムの設計・開発

– 教育・各種執筆活動• 日経ソフトウェア「とことん作って覚える! Java入門」連載中

• 「なぜ、あなたはJavaでオブジェクト指向開発ができないのか」

•• Seasar2Seasar2とのかかわりとのかかわり– S2Containerコミッタ、S2JMSコミッタ、S2JFaceコミッタ

Page 4: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.4

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

AOPAOPがなければ何が困る?がなければ何が困る?

• 具体例で考えてみよう!

– ジャンケンプログラムにロギング処理を追加したい!

Page 5: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.5

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

Log4jLog4jでロギング処理を追加しよう!でロギング処理を追加しよう!

• ジャンケンの手を決めるメソッドへロギング処理を追加<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

コンピュータの手を決めるクラス

人間の入力した手を読み取るクラス

人間の入力した手を読み取るクラス

ロギング処理を追加ロギング処理を追加 ロギング処理を追加ロギング処理を追加

Page 6: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.6

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

public class ComputerPlayer extends AbstractPlayer {private Tactics tactics;

private static final Logger logger = Logger.getLogger(ComputerPlayer.class);

public int showHand() {int hand = tactics.readTactics();logHand(hand);return hand;

}

public void setTactics(Tactics tactics) {this.tactics = tactics;

}

private void logHand(int hand) {switch (hand) {case Janken.STONE:logger.debug("コンピュータ:グー");break;

case Janken.SCISSORS:logger.debug("コンピュータ:チョキ");break;

case Janken.PAPER:logger.debug("コンピュータ:パー");break;

}}

}

BeforeBefore AfterAfter

・・・追加されたロギング処理

追加されたロギング処理追加されたロギング処理

public class ComputerPlayer extends AbstractPlayer {private Tactics tactics;

public int showHand() {int hand = tactics.readTactics();return hand;

}

public void setTactics(Tactics tactics) {this.tactics = tactics;

}}

Page 7: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.7

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

ロギング処理を共通化したい!ロギング処理を共通化したい!

• ロギング処理に重複部分があるのでなんとかしたい

共通処理を別クラスに分離

共通処理を別クラスに分離

HandLogger+logHand()

<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

public class ComputerPlayer extends AbstractPlayer {private Tactics tactics;

@Overridepublic int showHand() {

int hand = tactics.readTactics();HandLogger.logHand(PlayerType.COMPUTER, hand);return hand;

}}

ロギングモジュールのロギングモジュールの呼び出し部分は除去できない呼び出し部分は除去できない

Page 8: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.8

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

呼び出し部分が残ると何が問題か呼び出し部分が残ると何が問題か

• ロギングモジュールの呼び出し部が依存部分として残ってしまうロギング処理を削除しようとすると呼び出し元にも影響が出る

HandLogger+logHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

HandLogger+logHand()

単独での再利用が不可能!単独での再利用が不可能!

モジュール側の再利用は簡単・・・

モジュール側の再利用は簡単・・・

Page 9: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.9

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

似たようなクラスを作成するときの問題似たようなクラスを作成するときの問題

• 共通モジュールの呼び出しは開発者に依存してしまう

HandLogger+logHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

xxxxPlayer

+showHand()

新しいクラスを作るとき新しいクラスを作るとき開発者が呼び出しを忘れてしまう開発者が呼び出しを忘れてしまう

Page 10: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.10

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

非機能要件はモジュール単独分離が難しい非機能要件はモジュール単独分離が難しい

• 非機能要件に関する処理は、全機能に影響するため、モジュールとして分離しにくい

ロギング処理も非機能要件の一つ非機能要件・・・システムの本来の機能とは関係ないが、信頼性や保守性、使いやすさを向上させるための要件

機能要件A機能要件A 機能要件B機能要件B 機能要件C機能要件C 機能要件D機能要件D

非機能要件

各機能に共通する処理をモジュール化する方法はないの?

Page 11: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.11

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

アスペクト指向は関心事の分離からアスペクト指向は関心事の分離から

• システムを2種類の要件に分け、横断的関心事を分離するのがアスペクト指向の考え方

ビジネスAビジネスA ビジネスBビジネスB ビジネスCビジネスC ビジネスDビジネスD

セキュリティ(アクセス制御、情報隠蔽、承認、完全性・・・)

信頼性(バックアップ、分散、冗長性の確保・・・)

運用情報(監視、稼働状況、負荷管理、障害状況・・・)

マイグレーション(配備、設定、保守、開発計画・・・)

【出典】 『Seasar2で学ぶDIとAOP』(arton著、技術評論社)p20

横断的関心事(Cross cutting concern)

横断的関心事(Cross cutting concern)

中心的関心事(Core concern)

中心的関心事(Core concern)

Page 12: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.12

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

ジョインポイントとアドバイスジョインポイントとアドバイス

• アスペクト指向では、機能の中にジョインポイントを定義し、アドバイスをウィービングする

ビジネスAビジネスAビジネスBビジネスB

ビジネスCビジネスCビジネスDビジネスD

ジョインポイント(Joinpoint)処理を追加する場所

ジョインポイント(Joinpoint)処理を追加する場所

アドバイス(Advice)追加される処理

アドバイス(Advice)追加される処理

セキュリティ(アクセス制御、情報隠蔽、承認、完全性・・・)セキュリティ(アクセス制御、情報隠蔽、承認、完全性・・・)

信頼性(バックアップ、分散、冗長性の確保・・・)信頼性(バックアップ、分散、冗長性の確保・・・)

運用情報(監視、稼働状況、負荷管理、障害状況・・・)運用情報(監視、稼働状況、負荷管理、障害状況・・・)

マイグレーション(配備、設定、保守、開発計画・・・)マイグレーション(配備、設定、保守、開発計画・・・)

ウィービング(Weaving)処理を追加すること

ウィービング(Weaving)処理を追加すること

Page 13: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.13

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

どのようなジョインポイントがあるか?どのようなジョインポイントがあるか?

• ジョインポイント(Joinpoint)はアドバイスを挿入

可能なプログラム上の位置

① 呼び出されたメソッドの開始点

② 呼び出されたメソッドの終了点

③ メソッドの呼び出し地点

④ フィールドの参照、更新地点

⑤ クラスの生成地点

private int x;methodA () {

methodB();

x = x + 1;

methodC();

new XXX();

}

private int x;methodA () {

methodB();

x = x + 1;

methodC();

new XXX();

}

methodB () {

}

methodB () {

}

methodC () {}

methodC () {}

Page 14: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.14

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

ジョインポイントとアドバイスを結びつけるジョインポイントとアドバイスを結びつけるポイントカットポイントカット

• どのジョインポイントにどのアドバイスを結びつけるかはポイントカット(Pointcut)で指定する

プログラム実行の流れ(スレッド)

ポイントカット

アドバイスどのジョインポイントをどのアドバイスに結びつけるかを指定する

どのジョインポイントをどのアドバイスに結びつけるかを指定する

ジョインポイント

【出典】 『アスペクト入門』(千葉 滋 著、技術評論社)p47

Page 15: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.15

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

実際にどうやって実現するの?実際にどうやって実現するの?

•AOP(Aspect-Oriented Programming:アスペクト指向プログラミング)

はどうやって実現するの?

1.専用コンパイラを利用する方法

AOPを利用するには2種類の方法がある

2.DIコンテナを利用する方法

Page 16: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.16

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

専用コンパイラを利用する方法専用コンパイラを利用する方法

• AspectJによるAOPの実現

Javaソースコード

アスペクト(Aspect)

アドバイスとポイントカットを記述したもの

アドバイスとポイントカットを記述したもの

public aspect HandLogger {pointcut loggedMethods():

execution(void HumanPlayer.showHand())|| execution(void ComputerPlayer.showHand());

after():loggedMethods() {// ログ出力処理

}}

通常のJavaクラス通常のJavaクラス

AspectJコンパイラ

Javaクラスファイル

コンパイルと同時にウィービングを行って

クラスファイルを出力する

コンパイルと同時にウィービングを行って

クラスファイルを出力する

ポイントカットポイントカット

アドバイスアドバイス

Page 17: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.17

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

DIDIコンテナを利用する方法コンテナを利用する方法

• DIコンテナ(Seasar2)によるAOPの実現

Javaソースコード

アドバイス(Javaソースコード)

Diconファイル

Javaコンパイラ

Javaコンパイラ

DIコンテナ(Seasar2)

実行時に内部でウィービングを行う

実行時に内部でウィービングを行う

アスペクトを記述アスペクトを記述

Page 18: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.18

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

CoreConcernとCrossCuttingConcernを分離できた!

S2AOPS2AOPを体感してみよう!を体感してみよう!

• 「アスペクトでジャンケン」のロギング処理をS2AOPで書き直す

<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

<<interface>>

MethodInterceptor

<<abstract>>

AbstractInterceptor

HandInterceptor

+invoke()

Seasar2に含まれるクラス

Diconファイル

アスペクトを記述

ロギングに関する記述はナシ!

Page 19: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.19

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

S2AOPS2AOPでのでのDiconDiconファイルの記述ファイルの記述

• S2AOPではXML(Diconファイル)にアスペクトを記述する

<components><component name="player" class="org.seasar.jface.example.janken.impl.HumanPlayer"><aspect pointcut="showHand">handInterceptor</aspect>

</component>

<component name="computer" class="org.seasar.jface.example.janken.impl.ComputerPlayer"><aspect pointcut="showHand">handInterceptor</aspect>

</component>

<component name="handInterceptor" class="org.seasar.jface.example.janken.interceptors.HandInterceptor" /></components>

コンポーネントとして登録されたインターセプター(アドバイス)

コンポーネントとして登録されたインターセプター(アドバイス)

ウィービング対象のコンポーネント

ウィービング対象のコンポーネント

ウィービング対象のコンポーネント

ウィービング対象のコンポーネント

コンポーネントに対するアスペクト

コンポーネントに対するアスペクト

ポイントカットの指定(アドバイスを追加するメソッド)

ポイントカットの指定(アドバイスを追加するメソッド)

Page 20: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.20

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

S2AOPS2AOPの仕組みの仕組み

• ちょっとだけS2AOPの仕組みを紹介しましょう・・・

HumanPlayer

+showHand()

HandInterceptor

+invoke()

public Object invoke(MethodInvocation invocation) throws Throwable {// 元のメソッド実行前に行いたい処理invocation.proceed();// 元のメソッド実行後に行いたい処理

}

HumanPlayer$S2AOP

+showHand()

オーバーライド

SeasarがJavassistを利用して

実行中にサブクラスを自動生成

SeasarがJavassistを利用して

実行中にサブクラスを自動生成

Javassist:国産のバイトコートエンジニアリングライブラリhttp://www.csg.is.titech.ac.jp/~chiba/javassist/

More Info!

Page 21: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.21

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

Seasar2Seasar2の提供するインターセプターの提供するインターセプター

• TraceInterceptor– メソッド呼び出しのトレースを自動出力

• ThrowsInterceptor– 例外のキャッチを一括処理

• ToStringInterceptor– toString()メソッドを自動処理

• MockInterceptor– モックを使ったテストを支援

• DelegateInterceptor– メソッド呼び出しを別コンポーネントへ委譲

• SyncInterceptor– メソッド呼び出しを同期化

http://s2container.seasar.org/ja/aop.htmlMore Info!

Page 22: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.22

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

S2DAOS2DAOととAOPAOP

• S2DAOもAOPによって実現されている– インターフェースしか用意していないのに処理が行われるのはどうして??

<<interface>>

xxxDao+insert()+update()+delete()

xxxDao$S2AOP+insert()+update()+delete()

DaoInterceptor

S2AOPで自動生成された

実装クラス

S2AOPで自動生成された

実装クラス

ユーザが作成したインターフェース

ユーザが作成したインターフェース

S2Daoの提供するインターセプタがDaoとしての

機能を提供

S2Daoの提供するインターセプタがDaoとしての

機能を提供

アスペクト指向でソースコード生成を伴わないスマートなDAOが可能に!

アスペクト指向でソースコード生成を伴わないスマートなDAOが可能に!

http://s2dao.seasar.org/ja/s2dao.htmlMore Info!

Page 23: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.23

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

既存のクラスを拡張するインタータイプ宣言既存のクラスを拡張するインタータイプ宣言

• インタータイプ宣言とは– 既存のクラスの静的構造を変更するアスペクトの機能

• Seasar2.4で提供される新機能InterType– 既存のクラスに対してメソッドやフィールドを自由に追加可能

Point-x-y

+calcArea();

Point-x-y-color+calcArea();+setColor();

プログラム実行中に追加!

プログラム実行中に追加!

ソースコード自動生成に替わる手段として利用可能!ソースコード自動生成に替わる手段として利用可能!http://s2container.seasar.org/ja/aop.html#OriginalInterTypeMore Info!

Page 24: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.24

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

アスペクト指向をさらに知りたい方へアスペクト指向をさらに知りたい方へ

• 『アスペクト指向入門』-Java・オブジェクト指向からAspectJプログラミングへ

– 著:千葉 滋– 価格:¥2,480+税

– 出版社:技術評論社– ISBN:4-7741-2581-4

Page 25: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.25

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

ご質問についてご質問について

スピーカーブースでお待ちしています

気軽にお越しください

Page 26: 今さら人には聞けない 入門 - Seasar Foundation · DIコンテナを利用する方法 •DIコンテナ(Seasar2)によるAOPの実現 Javaソースコード アドバイス

© The Seasar Foundation and the others 2006. all rights reserved.26

Seasar ConferenceSeasar Conference2006 Autumn2006 Autumn

ご静聴ありがとうございました