Recommended
PDF
カッコいい SharePoint モダンサイトを作ろう
PDF
初めてでも大丈夫!SharePoint 開発の第一歩
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
Spring Fest 2018 Spring Bootで作るRESTful Web Service
PPTX
Amazon EKS への道 ~ EKS 再入門 ~
PPTX
Spring Boot ユーザの方のための Quarkus 入門
PDF
PDF
Form認証で学ぶSpring Security入門
PDF
PDF
PlaySQLAlchemy: SQLAlchemy入門
PPTX
え!?データがオンプレにあるけどPower BI で BI したいの?
PPTX
プロが解説!Hinemosによる運用管理テクニック!
PDF
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
PDF
ZOZOTOWNのマルチクラウドへの挑戦と挫折、そして未来
PDF
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
PDF
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
PPTX
JSON Value into Power Automate
PPTX
JIRA / Confluence の必須プラグインはこれだ
PDF
インフラエンジニアの綺麗で優しい手順書の書き方
PDF
MHA for MySQLとDeNAのオープンソースの話
PPTX
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
PDF
PPTX
PDF
OpenID ConnectとAndroidアプリのログインサイクル
PDF
【BS10】Microsoft と GitHub の開発エコシステムで、開発にドライブをかけよう!
PDF
PDF
PDF
PPT
Spring3.1概要 データアクセスとトランザクション処理
More Related Content
PDF
カッコいい SharePoint モダンサイトを作ろう
PDF
初めてでも大丈夫!SharePoint 開発の第一歩
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
Spring Fest 2018 Spring Bootで作るRESTful Web Service
PPTX
Amazon EKS への道 ~ EKS 再入門 ~
PPTX
Spring Boot ユーザの方のための Quarkus 入門
PDF
PDF
Form認証で学ぶSpring Security入門
What's hot
PDF
PDF
PlaySQLAlchemy: SQLAlchemy入門
PPTX
え!?データがオンプレにあるけどPower BI で BI したいの?
PPTX
プロが解説!Hinemosによる運用管理テクニック!
PDF
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
PDF
ZOZOTOWNのマルチクラウドへの挑戦と挫折、そして未来
PDF
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
PDF
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
PPTX
JSON Value into Power Automate
PPTX
JIRA / Confluence の必須プラグインはこれだ
PDF
インフラエンジニアの綺麗で優しい手順書の書き方
PDF
MHA for MySQLとDeNAのオープンソースの話
PPTX
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
PDF
PPTX
PDF
OpenID ConnectとAndroidアプリのログインサイクル
PDF
【BS10】Microsoft と GitHub の開発エコシステムで、開発にドライブをかけよう!
PDF
PDF
Viewers also liked
PDF
PPT
Spring3.1概要 データアクセスとトランザクション処理
PDF
PDF
Twitter sphere of #twitter4j #twtr_hack
PDF
PDF
PDF
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
PDF
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
PDF
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
Similar to Spring3.1概要 AOP & MVC
PPTX
AspectJによるJava言語拡張 2012.09.07
PPTX
PDF
【18-B-4】ソースコード品質、大丈夫ですか? ~静的検証のススメ~
PDF
AgileTourOsaka2011 関係者に理解してもらえるアジャイル開発にむけて
PDF
PDF
Agility@Scale(アジャイル開発のスケールアップ)を実現する14のベストプラクティス
PDF
AJ2010_20100409_maegawasensei
PDF
Agile Estimating And Planning
PDF
PDF
アダプタブル・ウォーターフォール開発の事例 ~想定外の作業はチケットで補完せよ!~
PDF
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter)
PDF
PDF
PDF
Javaセキュアコーディングセミナー東京第1回演習の解説
PDF
PDF
Javaセキュアコーディングセミナー東京第4回講義
PDF
元気が出るチケット駆動開発 - 補完型TiDDの経験 - @XP祭り関西2010
PDF
俺も受託開発〜準委任契約によるふつうのソフトウェア開発〜
PPT
PDF
More from Yuichi Hasegawa
PDF
PDF
Spring 5でSpring Testのここが変わる_公開版
PDF
PDF
PPTX
マイクロサービス入門(Spring fest 2017)
PDF
20170525 jsug バッチは地味だが役に立つ
PDF
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
PDF
Spring Day 2016 springの現在過去未来
PDF
PDF
PDF
PDF
PDF
[Jjug]java small object programming
PDF
[豆ナイト]Java small object programming
PDF
PDF
Recently uploaded
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):東京大学情報基盤センター テーマ1/2/3「Society5.0の実現を目指す『計算・データ・学習...
PDF
安価な ロジック・アナライザを アナライズ(?),Analyze report of some cheap logic analyzers
PPTX
PDF
visionOS TC「新しいマイホームで過ごすApple Vision Proとの新生活」
PDF
基礎から学ぶ PostgreSQL の性能監視 (PostgreSQL Conference Japan 2025 発表資料)
PDF
第25回FA設備技術勉強会_自宅で勉強するROS・フィジカルAIアイテム.pdf
Spring3.1概要 AOP & MVC 1. 2. 問題
• インスタンス変数に宣言したのと同じ型
のインスタンスをインジェクションして
もらうためのアノテーションは?
• インスタンス化され、インジェクション
されるために、クラス宣言の前に書くア
ノテーションは?
• 結局、DIコンテナって何のためにあるの
か?
2
3. 4. 5. AOPを使ってもっと部品化する
• AOPを使えば処理を後からクラスに追加できる
‒ 例:トレースログを追加する
find()を呼ぶ
DaoImpl
ServiceImpl
find()
Dao
public class DaoImpl extends Dao{
>java ・・・
・・・
16:00:01 *Start* find() DaoImpl
public List find() {
16:00:02 *End* find() DaoImpl
List list = select();
17:02:12 *Start* find() DaoImpl
return list;
17:02:13 *End* find() DaoImpl
}
}
実行結果
5
6. 7. 8. 9. 10. 11. After Returning Advice
• Joinpointが正常終了した後に実行される
method()
return
Client After Returning Advice Servant
Exception
メソッドの実行後に正常終了時
に割り込む
11
12. 13. 14. 15. 16. AOPの主な利用方法
• 各クラスに記述されている同一の処理を抜き出し、ひと
まとめにして、既存のクラスに後から追加する
‒ ライブラリとの違い
• ライブラリは呼び出さないといけない
• AOPは勝手に追加される
• 追加すると便利な処理
‒ トランザクション管理
• トランザクション管理は難しいくプログラマに任せられない
‒ ログ管理
• メソッドの開始と終了のトレースログが正しく出力されない
‒ 誰もフォーマットを守らない
‒ トレースログを追加し忘れる
‒ 例外管理
• 処理の途中でExceptionが握りつぶされてしまう
‒ Exceptionを実行時例外にする
16
17. 18. 19. 問題 書いてないけど?
• 例えば
‒ アノテーション
• メリット:定義ファイルの管理が不要
• デメリット:プログラマにアノテーションを意識
‒ とか、定義ファイルのメリットとかデメリット
19
20. 21. 22. アノテーション一覧
• アノテーションを利用したAOP
‒ Bean定義ファイルの記述が簡潔になる
‒ ソースコードに記述することで管理が煩雑
アノテーション
説明
@Aspect Adviceとなるクラスを指定するアノテーション
@Around Around Adviceとなるメソッドを指定するアノテーション
@Before Before Adviceとなるメソッドを指定するアノテーション
@After After Adviceとなるメソッドを指定するアノテーション
@AfterReturning
After Returning Adviceとなるメソッドを指定するアノテーション
@AfterThrowing After Throwing Adviceとなるメソッドを指定するアノテーション
22
23. アドバイス詳細(1)
• Before, After
‒ @After( Primitiveポイントカット )
• メソッド名は任意、メソッドのパラメータと戻り値はなしでも可能。
メソッド内で、アスペクト対象となっているメソッド名やパラメー
タ,戻り値などの取得をする場合は、パラメータにJoinPoint
• メソッド内で、アスペクト対象となっているメソッドを呼び出す必
要はない
@Before(“execution(* exMethod())”)
public void hoge() {
・・・
}
23
24. アドバイス詳細(2)
• Around
‒ @Around( Primitiveポイントカット )
• メソッド名は任意、メソッドのパラメータには必
ずProceedingJoinPointが必要、戻り値はアスペ
クト対象のメソッドにあわせる
• メソッド内で、アスペクト対象となっているメ
ソッドを呼び出す必要がある
‒ ProceedingJoinPoint#proceed()メソッド
» Object proceed() throws Trowable
• メソッド内で、アスペクト対象となっているメ
ソッド名やメソッドのパラメータの取得は
ProceedingJoinPointを介しておこなう
24
25. アドバイス詳細(3)
• Around
‒ 戻り値はアスペクト対象にあわせる
public String getMessage() {
return “hello!”; アスペクト対象のメソッド
}
@Around(“execution(* getMessage())”)
public String fuga(ProceedingJoinPoint pjp)
throws Throwable {;
String msg = (String)pjp.proceed();
return msg;
}
25
26. アドバイス詳細(4)
public int getFigure() {
return 100; アスペクト対象のメソッド
}
@Around(“execution(* getFigure())”)
public int fuga(ProceedingJoinPoint pjp)
throws Throwable {;
Integer figure= (Integer)pjp.proceed();
return figure.intValue();
}
26
27. アドバイス詳細(5)
• Around
‒ ProceedingJoinPointの使い方
メソッド名の取得
Signature sig = pjp.getSignature();
System.out.println("Sig: " + sig.getName());
パラメータの取得(最初のパラメータ)
Object[] os = pjp.getArgs();
System.out.println("Args: " + os[0]);
27
28. 問題∼重複してたらどうなる?
@Around(“execution(* add())”)
public int hoge (ProceedingJoinPoint pjp)
throws Throwable {;
Integer figure= (Integer)pjp.proceed();
return figure.intValue(); これと同じhogehogeメソッド
} が存在したら?
private int x;
public int add(int i) {
x = x + i; アスペクト対象のメソッド
return x;
}
28
29. アドバイス詳細(6)
• AfterReturning
‒ @AfterReturning(value= Primitiveポイント
カット , returnig = 戻り値の変数名 )
• メソッド名は任意、メソッドのパラメータはアス
ペクト対象となっているメソッドの戻り型とアノ
テーションのretuning属性で指定した変数名
• メソッド内で、アスペクト対象となっているメ
ソッドを呼び出す必要はない
29
30. アドバイス詳細(7)
public String exMethod() {
return “hello!”; アスペクト対象のメソッド
}
@AfterReturning(value=“execution(* exMethod())”,
returning=“ret”)
public String hoge(String ret) {
System.out.println(“Return: “ + ret);
}
30
31. アドバイス詳細(8)
• AfterThrowing
‒ @AfterReturning(value= Primitiveポイント
カット , throwing = 例外の変数名 )
• メソッド名は任意、メソッドのパラメータはアス
ペクト対象となっているメソッドの戻り型とアノ
テーションのthrowing属性で指定した変数名
• メソッド内で、アスペクト対象となっているメ
ソッドを呼び出す必要がない
31
32. 33. アドバイス詳細(10)
• AfterThrowing
@AfterThrowing(value=“execution(* exMethod())”, throwing=“ex”)
public String foo(Throwable ex) {
System.out.println(“Exception Msg: “ + ex.getMessage());
}
@AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”)
public String var(HogeException ex) {
System.out.println(“Exception Msg: “ + ex.getMessage());
}
@AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”)
public String hoge(Exception ex) {
System.out.println(“Exception Msg: “ + ex.getMessage());
}
33
34. 35. Primitiveポイントカット
Primitive
ポイントカット
概要
execution
呼出先の「メソッド」、「コンストラクタ」を指定する。
within
呼出元の「クラス」を指定する。
withinをPointcutに指定すると、指定されたクラスから呼出される、メソッ
ド等が選択されることになる。
対象は、指定されたクラスで宣言されたメソッドに限定され、指定された
クラスの親クラスで宣言されたメソッド内は対象外となる。
this
呼出元の「クラス」を指定する。
thisをPointcutに指定すると、指定されたクラスから呼出される、メソッド
等が選択されることになる。
withinとは、親クラスで定義されたメソッドの呼出しも対象とする点が異な
る。
target
呼出先の「クラス」を指定する。
ただし、呼出先のstaticフィールドは対象外となる。
args
呼出先「メソッド」の引数の型を指定する。
※Primitiveポイントカット:あらかじめ用意されているポイントカットのこと
35
36. executionの基本構文
• execution(メソッドの修飾子△メソッドの戻り値型△
パッケージ.クラスまたはインタフェース.メソッド名
(仮引数の型|,仮引数の型…|) △throws 例外)
• 「メソッドの修飾子(publicやprivateは省略可能)」や
「throws△例外」は省略することが可能
• メソッドの戻り値型、パッケージやクラス名、インタ
フェース名にはワイルドカード(*)の利用が可能
• 仮引数に(..)を記述すると任意の個数の引数と一致さ
せることが可能
36
37. ポイントカットで利用できる論理演算子
論理 説明
演算子
|| または 論理和を意味する論理演算子
or
例)
execution(* *..AopExBean.exMethod()) or execution(* *..AopExBeanParent.exMethod())
→AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定
&& また 論理積を意味する論理演算子
は and
例)
execution(* *..AopExBean.exMethod()) && execution(* *..AopExBeanParent.exMethod())
→AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定
! または 否定を意味する論理演算子。
not
例)
execution(* exMethod()) and not execution(* *..AopExBeanParent.*())
→AopExBeanParent以外のクラス(インタフェース)のメソッドexMethodを指定
37
38. コーディング例(1)
@Aspect
public class AspectMessage {
@After("execution(* exMethod())")
public void after() {
// メソッド終了後に動作するAdvice
System.out.println("after called");
}
@Before("execution(* exMethod())")
public void before() {
// メソッド開始時に動作するAdvice
System.out.println("before called");
}
38
39. 40. コーディング例(3)
@AfterReturning(value="execution(* exMethod())", returning="ret")
public void afterReturning(String ret) {
// メソッド呼出が例外の送出なしに終了した際に動作するAdvice
System.out.println("after returning called");
System.out.println("return value = " + ret);
}
@AfterThrowing(value="execution(* exMethod())", throwing="ex")
public void afterThrowing(Throwable ex) {
// メソッド呼出が例外の送出なしに終了した際に動作するAdvice
System.out.println("after throwing called");
System.out.println("exception value = " + ex.toString());
}
}
40
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
xmlns:aop=http://www.springframework.org/schema/aop
xsi:schemaLocation=”
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
…
<aop:aspectj-autoproxy/>
…
</beans>
41
42. 43. それでも書きたい定義ファイル(1)
・・・
<aop:config>
<aop:aspect id="myAspect" ref="aspectMessage">
<aop:pointcut id="fuga"
expression="execution(* getMessage())"/>
<aop:before pointcut-ref="fuga" method="foo"/>
<aop:after pointcut-ref="fuga" method="var"/>
<aop:around pointcut-ref="fuga" method="hoge"/>
</aop:aspect>
</aop:config>
43
44. それでも書きたい定義ファイル(2)
<aop:config>
<aop:aspect id="myAspect2" ref="aspectMessage2">
<aop:pointcut id="fuga2"
expression="execution(* getMessage())"/>
<aop:after pointcut-ref="fuga2" method="hoge"/>
</aop:aspect>
</aop:config>
・・・
<bean id="aspectMessage" class="sample.aop.AspectMsg" />
<bean id="aspectMessage2" class="sample.aop.AspectMsg2" />
・・・
44
45. コーディング例
public class AspectMessage {
public void after() {
// メソッド終了後に動作するAdvice
System.out.println("after called");
}
public void before() {
// メソッド開始時に動作するAdvice
System.out.println("before called");
}
・・・以下省略
45
46. 問題 消すことできる?
<aop:config>
<aop:aspect id="myAspect2" ref="aspectMessage2">
<aop:pointcut id="fuga2"
expression="execution(* getMessage())"/>
beanを定義している2行
<aop:after pointcut-ref="fuga2" method="hoge"/>
</aop:aspect>
</aop:config>
・・・
<bean id="aspectMessage2" class="sample.aop.AspectMsg2" />
<bean id="aspectMessage2" class="sample.aop.AspectMsg" />
・・・
46
47. 48. アーキテクチャ・リファクタリング(1/5)
Employee
Employee
FindAction MySql RDB
Service
Dao
ブラウザ
• 表示と永続化のフレームワーク導入済
• インタフェース未使用(もちろんDI,AOPも)
‒ チーム開発がしずらい
‒ 変更、機能拡張、テストが容易ではない
• 連続性も阻害
‒ Conecctionの引き回し、検査時例外の伝搬
48
49. アーキテクチャ・リファクタリング(2/5)
インタフェースの導入
Employee Employee
Service Dao
<<Singleton>> <<Singleton>>
FindAction Employee Employee MySQL
ServiceImpl DaoMySql
ブラウザ
RDB
利用
利用
生成
生成
Factory
• メリット
‒ インタフェースを区切りとして、チーム開発がやりやすくなった
‒ 変更、機能拡張、テストが容易になった
• デメリット
‒ Factoryを実装する必要がある
‒ クラスはFactoryに依存する
49
50. アーキテクチャ・リファクタリング(3/5)
DIの導入
Employee Employee
Service Dao
Employee Employee
FindAction MySQL
ServiceImpl DaoMySql
ブラウザ
RDB
生成
生成
Injection Injection
DIコンテナ
• Factoryを実装する必要がない
• クラスはDIコンテナに依存しない
50
51. アーキテクチャ・リファクタリング(4/5)
DIコンテナ導入後のソースコード
• トランザクション管理やログ出力、例外処理が残っている
Employee ‒ 分岐が多いため、テストの量が多くなる
ServiceImpl ‒ 共通化できる部分が隠蔽できていない
‒ 例外処理とConnectionの引き渡しによる連続性の阻害がある
public class EmployeeServiceImpl" } catch(Exception e) {!
implements EmployeeService{" conn.rollback();!
@Autowired! ・・・
private EmployeeDao dao;" } finally {!
・・・
conn.close();!
public List findAll() throws Exception {! ・・・
if(Log.flag) { System.out.println(“***Start”); }! }!
Connection conn = null;" if(Log.flag) { System.out.println(“***End”); }"
・・・
return employeeList;"
//EmployeeDao dao ! }"
// = (EmployeeDao)Factory.create(KEY);!
・・・
List employeeList = null;"
try {"
employeeList = dao.findAll(conn);"
conn.commit();!
51
52. アーキテクチャ・リファクタリング(5/5)
AOP導入後のソースコード
• 共通ライブラリを廃止してAOPを導入
• 連続性の確保
‒ トランザクション管理、ログ出力、例外処理はAOPで実現しているため、ソースコード上から
はなくなっている
‒ Advice実装されており、なくなっている訳ではない
• ソースコードの記述量が減り、バグの数も低下、開発者の作業も軽減
• テストの容易性も向上
public class EmployeeServiceImpl ! 書くことがなくなりました・・・!
implements EmploeeService {!
@Autowired!
private EmployeeDao dao;!
public List findAll() {!
return dao.findAll();!
}!
・・・
52
53. 54. 55. Spring MVCとは
• Spring Frameworkに含まれるWeb
MVCフレームワーク
‒ 初期のSpring Frameworkの段階から含まれ
ている
‒ StrutsやJSFと競合
• 特徴
‒ DIコンテナとの親和性
‒ きれいな設計
• インタフェースを使用して部品化
55
56. Spring MVCのController
DIの導入
Employee Employee
Service Dao
Employee Employee
XxxController MySQL
ServiceImpl DaoMySql
ブラウザ
RDB
生成
生成
生成
Injection
Injection
DIコンテナ
56
57. 58. 簡単になったSpring MVC
• Spring 3.xのSpring MVC
‒ Springの新機能を導入
• アノテーションにより設定がシンプルになり、わ
かりやすくなった
• component-scanにより設定ファイルが最低限で
すむようになった
‒ あいかわらず日本語の情報は少ない
• 英語のマニュアルを読みましょう
58
59. デモ
• STS(SpringSource Tool Suite)で作成
1. メニューからNew->Project
2. SpringSource Tool Suite->Spring
Template Projectを選択
3. Spring MVC Projectを選択
59
60. 動作概要
<<controller>>
Model
HomeController
"serverTime"
Date
home()
③
(現在の日時)
Dispatcher
ブラウザ
①
Servlet
(ほか色々)
<<jsp>>
/WEB-INF/views/home.jsp
⑥
60
61. HomeController
DIコンテナにより
自動で読み込まれる
(component-scan)
HTTPメソッドがGETで
@Controller 「/」へアクセスした際に
public class HomeController { 実行される
@RequestMapping(value = "/", method = GET)
public String home(Model model) { Viewに渡したいオブジェクトを
Date date = new Date(); 設定する
model.addAttribute("serverTime", date);
return "home";
}
View名をreturnする
}
※少し手を加えシンプルにしています
61
62. home.jsp
<html>
<head>
<title>Home</title> Modelに設定したオブジェクトは
</head> 自動的にHttpServletRequestに
設定されている
<body>
<h1>Hello world! </h1>
<p>The time on the server is ${serverTime}.</p>
</body>
</html>
※少し手を加えシンプルにしています
62
63. 64. 引数色々①
// リクエストパラメータを取得(「/person?id=10」などでアクセス)
@RequestMapping(value = "/person", method=GET)
public String showPerson1 (
@RequestParam("id") int id, Model model) {
Person person = findById(id);
model.addAttribute("person", person);
・・・
// URLの値を取得(「/person/10」などでアクセス)
@RequestMapping(value = "/person/{id}", method=GET)
public String showPerson2(
@PathVariable("id") int id, Model model) {
Person person = findById(id);
model.addAttribute("person", person);
・・・
64
65. 引数色々②
// 画面からの入力をマッピング(formからデータを送信)
@RequestMapping(value = "/person", method = POST)
public String registerPerson(@ModelAttribute Person person) {
register(person);
・・・
// ほかにも色々
@RequestMapping("/foo")
public String foo(
Model model, WebRequest req, WebResponse res,
Cookie cookie, Locale locale,
HttpServletRequest sreq, HttpServletResponse sres) {
・・・
65
66. その他の機能
• Session管理
‒ @SessionAttributes(model名)をクラスに設定すると、Modelに追加
したオブジェクトはHttpSessionに追加される
‒ @ModelAttribute(model名)を引数に設定すると、Sessionのオブジェ
クトが引数に渡される
‒ SessionStatus#setComplete()でHttpSession内のオブジェクトが破
棄される
• ControllerごとにSession内のオブジェクトを管理可能
• 入力チェック(Validation)
‒ JSR-303(Bean Validation)に対応
• @NotNull String id;
• @Length(max = 30) String name;
‒ Validation対象の引数に@Validを設定する
• 例外処理
‒ 例外発生時に実行するメソッドに@ExceptionHandler
(FooException.class)
66
67.