• 検索結果がありません。

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

N/A
N/A
Protected

Academic year: 2021

シェア "今さら人には聞けないAOP入門"

Copied!
26
0
0

読み込み中.... (全文を見る)

全文

(1)

1

Seasar Conference

Seasar Conference

2006 Autumn

2006 Autumn

Seasar Conference

Seasar Conference

2006 Autumn

今さら人には聞けない

今さら人には聞けない

AOP

AOP

入門

入門

2006.11.12

エスエムジー株式会社

小森 裕介([email protected]

(2)

はじめに

はじめに

そんなことはない!

・・・と思います

でも、AOPが開発の中で

一般的になりつつあるのもまた事実・・・

そろそろ

『知らない』

って言えなくなってきたアナタに、

AOPの基礎を

で伝授します!

「えっ!?AOPって、もう

『今さら聞けない』

の?」

(3)

3

Seasar Conference

Seasar Conference

2006 Autumn

はじめまして!

はじめまして!

名前:

名前:

小森 裕介

Blog

Blog

http://d.hatena.ne.jp/y-komori/

所属:

所属:

エスエムジー株式会社(http://www.smg.co.jp)

主な仕事:

主な仕事:

– Javaによる集中監視制御システム設計・開発

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

– 教育・各種執筆活動

• 日経ソフトウェア

「とことん作って覚える! Java入門」

連載中

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

Seasar2

Seasar2

とのかかわり

とのかかわり

– S2Containerコミッタ、S2JMSコミッタ、S2JFaceコミッタ

(4)

AOP

AOP

がなければ何が困る?

がなければ何が困る?

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

(5)

5

Seasar Conference

Seasar Conference

2006 Autumn

Log4j

Log4j

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

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

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

<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

コンピュータの

手を決めるクラス

人間の入力した手を

読み取るクラス

人間の入力した手を

読み取るクラス

ロギング処理を追加

ロギング処理を追加

ロギング処理を追加

ロギング処理を追加

(6)

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;

}

}

Before

Before

After

After

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

追加されたロギング処理

追加されたロギング処理

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;

}

}

(7)

7

Seasar Conference

Seasar Conference

2006 Autumn

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

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

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

共通処理を

別クラスに分離

共通処理を

別クラスに分離

HandLogger

+logHand()

<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

public class ComputerPlayer extends AbstractPlayer {

private Tactics tactics;

@Override

public int showHand() {

int hand = tactics.readTactics();

HandLogger.logHand(PlayerType.COMPUTER, hand);

return hand;

}

}

ロギングモジュールの

ロギングモジュールの

呼び出し部分は除去できない

呼び出し部分は除去できない

(8)

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

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

• ロギングモジュールの呼び出し部が依存部分として残ってしまう

ロギング処理を削除しようとすると

呼び出し元にも影響

が出る

HandLogger

+logHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

HandLogger

+logHand()

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

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

モジュール側の

再利用は簡単・・・

モジュール側の

再利用は簡単・・・

(9)

9

Seasar Conference

Seasar Conference

2006 Autumn

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

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

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

HandLogger

+logHand()

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

xxxxPlayer

+showHand()

新しいクラスを作るとき

新しいクラスを作るとき

開発者が呼び出しを忘れてしまう

開発者が呼び出しを忘れてしまう

(10)

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

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

• 非機能要件

に関する処理は、全機能に影響するため、

モジュールとして分離しにくい

ロギング処理も非機能要件の一つ

非機能要件・・・システムの本来の機能とは関係ないが、

信頼性や保守性、使いやすさを向上させるための要件

機能要件A

機能要件A

機能要件B

機能要件B

機能要件C

機能要件C

機能要件D

機能要件D

非機能要件

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

(11)

11

Seasar Conference

Seasar Conference

2006 Autumn

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

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

• システムを2種類の要件に分け、

横断的関心事

分離するのが

アスペクト指向

の考え方

ビジネスA

ビジネスA

ビジネスB

ビジネスB

ビジネスC

ビジネスC

ビジネスD

ビジネスD

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

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

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

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

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

横断的関心事

(Cross cutting concern)

横断的関心事

(Cross cutting concern)

中心的関心事

(Core concern)

中心的関心事

(12)

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

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

• アスペクト指向では、機能の中に

ジョインポイント

を定義し、

アドバイス

ウィービング

する

ビジネスA

ビジネスA

ビジネスB

ビジネスB

ビジネスC

ビジネスC

ビジネスD

ビジネスD

ジョインポイント

(Joinpoint)

処理を追加する場所

ジョインポイント

(Joinpoint)

処理を追加する場所

アドバイス

(Advice)

追加される処理

アドバイス

(Advice)

追加される処理

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

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

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

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

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

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

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

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

ウィービング

(Weaving)

ウィービング

(Weaving)

(13)

13

Seasar Conference

Seasar Conference

2006 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 () {

}

(14)

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

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

ポイントカット

ポイントカット

• どのジョインポイントにどのアドバイスを結び

つけるかは

ポイントカット

(Pointcut)

で指定する

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

ポイントカット

アドバイス

どのジョインポイントを

どのアドバイスに結び

つけるかを指定する

どのジョインポイントを

どのアドバイスに結び

つけるかを指定する

ジョインポイント

(15)

15

Seasar Conference

Seasar Conference

2006 Autumn

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

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

• AOP

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

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

1.

専用コンパイラ

を利用する方法

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

(16)

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

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

• AspectJによるAOPの実現

Javaソースコード

アスペクト

(Aspect)

アドバイスとポイントカット

を記述したもの

アドバイス

ポイントカット

を記述したもの

public

aspect

HandLogger {

pointcut

loggedMethods():

execution(void HumanPlayer.showHand())

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

after():loggedMethods() {

// ログ出力処理

}

通常のJavaクラス

通常のJavaクラス

AspectJ

コンパイラ

Javaクラスファイル

コンパイルと同時に

ウィービングを行って

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

コンパイルと同時に

ウィービング

を行って

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

ポイントカット

ポイントカット

アドバイス

アドバイス

(17)

17

Seasar Conference

Seasar Conference

2006 Autumn

DI

DI

コンテナを利用する方法

コンテナを利用する方法

• DIコンテナ

(Seasar2)

によるAOPの実現

Javaソースコード

アドバイス

(Javaソースコード)

Diconファイル

Java

コンパイラ

Java

コンパイラ

DIコンテナ

(Seasar2)

実行時に内部で

ウィービングを行う

実行時に

内部で

ウィービング

を行う

アスペクトを記述

アスペクト

を記述

(18)

CoreConcern

S2AOP

S2AOP

を体感してみよう!

を体感してみよう!

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

<<interface>>

Player

<<abstract>>

AbstractPlayer

ComputerPlayer

+showHand()

HumanPlayer

+showHand()

<<interface>>

MethodInterceptor

<<abstract>>

AbstractInterceptor

HandInterceptor

+invoke()

Seasar2に含まれるクラス

Diconファイル

ロギングに関する

記述は

ナシ!

(19)

19

Seasar Conference

Seasar Conference

2006 Autumn

S2AOP

S2AOP

での

での

Dicon

Dicon

ファイルの記述

ファイルの記述

• 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>

コンポーネントとして登録された

インターセプター(アドバイス)

コンポーネントとして登録された

インターセプター(

アドバイス

ウィービング対象の

コンポーネント

ウィービング対象の

コンポーネント

ウィービング対象の

コンポーネント

ウィービング

対象の

コンポーネント

コンポーネントに対する

アスペクト

コンポーネントに対する

アスペクト

ポイントカットの指定

(アドバイスを追加するメソッド)

ポイントカット

の指定

(アドバイスを追加するメソッド)

(20)

S2AOP

S2AOP

の仕組み

の仕組み

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

HumanPlayer

+showHand()

HandInterceptor

+invoke()

public Object invoke(MethodInvocation invocation) throws Throwable {

// 元のメソッド実行前に行いたい処理

invocation.proceed();

// 元のメソッド実行後に行いたい処理

}

HumanPlayer$S2AOP

+showHand()

オーバーライド

SeasarがJavassistを利用して

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

SeasarがJavassistを利用して

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

(21)

21

Seasar Conference

Seasar Conference

2006 Autumn

Seasar2

Seasar2

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

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

• TraceInterceptor

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

• ThrowsInterceptor

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

• ToStringInterceptor

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

• MockInterceptor

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

• DelegateInterceptor

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

• SyncInterceptor

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

http://s2container.seasar.org/ja/aop.html

More Info!

(22)

S2DAO

S2DAO

AOP

AOP

• S2DAOもAOPによって実現されている

– インターフェースしか用意していないのに処理が行われるのはどうして??

<<interface>>

xxxDao

+insert()

+update()

+delete()

xxxDao$S2AOP

+insert()

+update()

+delete()

DaoInterceptor

S2AOPで自動生成された

実装クラス

S2AOPで自動生成された

実装クラス

ユーザが作成した

インターフェース

ユーザが作成した

インターフェース

S2Daoの提供する

インターセプタがDaoとしての

機能を提供

S2Daoの提供する

インターセプタがDaoとしての

機能を提供

アスペクト指向でソースコード生成を

アスペクト指向でソースコード生成を

伴わないスマートなDAOが可能に!

(23)

23

Seasar Conference

Seasar Conference

2006 Autumn

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

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

• インタータイプ宣言とは

– 既存のクラスの静的構造を変更するアスペクトの機能

• Seasar2.4で提供される新機能InterType

– 既存のクラスに対して

メソッドやフィールドを自由に追加可能

Point

-x

-y

+calcArea();

Point

-x

-y

-color

+calcArea();

+setColor();

プログラム実行中に

追加!

プログラム実行中に

追加!

ソースコード自動生成に替わる手段として利用可能!

ソースコード自動生成に替わる手段として利用可能!

http://s2container.seasar.org/ja/aop.html#OriginalInterType

More Info!

(24)

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

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

• 『アスペクト指向入門』

-

Java・オブジェクト指向からAspectJプログラミングへ

– 著:千葉 滋

– 価格:¥2,480+税

– 出版社:技術評論社

– ISBN:4-7741-2581-4

(25)

25

Seasar Conference

Seasar Conference

2006 Autumn

ご質問について

ご質問について

スピーカーブースで

お待ちしています

気軽にお越しください

(26)

ご静聴

参照

関連したドキュメント

あれば、その逸脱に対しては N400 が惹起され、 ELAN や P600 は惹起しないと 考えられる。もし、シカの認可処理に統語的処理と意味的処理の両方が関わっ

平成 29 年度は久しぶりに多くの理事に新しく着任してい ただきました。新しい理事体制になり、当団体も中間支援団

は︑公認会計士︵監査法人を含む︶または税理士︵税理士法人を含む︶でなければならないと同法に規定されている︒.

分だけ自動車の安全設計についても厳格性︑確実性の追究と実用化が進んでいる︒車対人の事故では︑衝突すれば当

【消費税】 資産の譲渡等に該当しない (処理なし)。. 【法人税】

この素晴らしい DNA

り分けることを通して,訴訟事件を計画的に処理し,訴訟の迅速化および低

 根津さんは20歳の頃にのら猫を保護したことがきっかけで、保健所の