山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

AOPの使い道

昨日のAOPの使い道ですが、あるシステムを以前外注で作ったときに

なんとJPAのEntityManagerが作りっぱなしでcloseされていない

ようになっていました。

通常であれば直させるのですがいろいろあって直してもらえない

状況になってしまいました。

今一応本番稼働しているのですが使っているとどんどんDBコネクションが

増えてしまいます。

これを何とかしたいのですが、全部直すと100か所くらい直して

テストしないといけません。

そのためずっと手を付けられないままになっていました。

そこでAOPです。

EntityManagerFactory.createEntityManager()の返り値を

捕捉してThreadLocalに入れます。

ServletFilterで一連の処理が終わった後にThreadLocalに入っている

EntityManagerを全部closeします。

コードの変更もテストも少しで済みます。

もれもありません。

素晴らしい。


昨日の技術情報に少し追加します。

LoadtimeWeavingがデフォルトの状態だとorg.jboss.パッケージ以外

全部が対象になるようです。

そうするとOracleのドライバやStrutsなどのクラスにも全部AOP

織り込もうとしてしまい、できないクラスについてログにエラーが

多数出力されます。

対象を最小限に絞り込むために、

deploy/jboss-aop-jdk50.deployer/META-INF/jboss-service.xml

の設定を変更します。

<attribute name="Include">org.jboss.test, org.jboss.injbossaop, AOPしたいパッケージ</attribute>

<attribute name="Exclude">*</attribute>


pointcutをEntityManagerFactory.createEntityManager()のexecuteに

したかったのですが、うまくいきませんでした。

クラスローダが違うのか、AOP起動前に読み込まれているなどが

ありそうです。

callの設定にして呼び出し側にAOPを織り込むことでうまく動きました。

設定は以下のような形です。

  <bind pointcut="call(* javax.persistence.EntityManagerFactory->createEntityManager())">