Java:SpringMVCでAOPする
Last-modified: 2014-01-03 (金) 22:51:40 (3620d)
Top / Java:SpringMVCでAOPする
Java:SpringMVCでAOPする †
SpringMVCでAOPをしようとしたときにしたときにちょっとハマったのでメモ。
前提 †
- Spring3.1を使用
- SpringMVCは既に動作している状況
依存ライブラリの追加 †
以下の依存ライブラリをpomに追加します。
- spring-aop
- aspectjrt
- aspectjweaver
- cglib
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency>
SpringBean?定義への設定追加 †
AOPするには、SpringMVCのDispatcherServlet?が読み込むBean定義に以下の内容が必要です。
- <context:component-scan .../>
- <mvc:annotation-driven />
- <context:annotation-config/>
- <aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
ちなみに、小生の環境では、上2つはSpringMVCを動作させるために既に設定してあったので、下2つを追加しました。
AOPするクラスを作成 †
以下のサンプルはアノテーションベースです。
簡単な仕様は以下のとおり。
- PointCut?はパッケージ名が*..controllerであるクラスのすべてのメソッドを対象
- AdviceはAround
@Aspect @Component public class MyAspect { @Around ("execution(* *..controller.*.*(..))") public Object before(ProceedingJoinPoint pjp){ Log log = LogFactory.getLog(pjp.getSignature().getDeclaringType()); log.debug(pjp.getSignature() + ":" + pjp.getArgs() + "is called"); Object ret = null; try { ret = pjp.proceed(); } catch (Throwable e) { // TODO 自動生成された catch ブロック log.error(e.getStackTrace(), e); } return ret; } }
ちなみに、備忘のためにPointCut?の構文を。
execution(メソッドの修飾子▲メソッドの戻り値型▲パッケージ.クラスまたはインタフェース.メソッド名(引数の型 | 引数の型……)▲throws▲例外)
- メソッドの修飾子、パッケージ名、クラス名、throwsは省略可能
- パッケージをワイルドカードで指定する場合は、*..と記述する(*は.を含まないため)
- メソッドの引数に「..」を指定すると、何でも一致するようになる
ちょっとハマったこと †
最初は、依存関係に以下の3つしか入れてなくて、
- spring-aop
- aspectjrt
- aspectjweaver
こんなエラーが出ました。
1 03, 2014 5:36:25 午後 org.springframework.web.servlet.FrameworkServlet initServletBean 重大: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexController' defined in file ……………………… Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
して、「cglib」を依存関係に足したらうまく行ったって感じでしたw