springにはAOPの概念があり、ビジネスロジックの本質とは異なった処理を別クラスに定義して、ビジネスロジックの実行前後などで共通処理として織り込む(インジェクションする)ことが出来ます。
@Before、@Afterは、springで使われる頻度の高いインジェクト方式です。
今回は基本的な@Before、@Afterの使い方を紹介していきます。
目次
- 特定のパッケージを指定した@Beforeと@After
- 特定のパッケージ配下(サブクラスを含)全てを指定した@Beforeと@After
- 特定のクラスを指定した@Beforeと@After
- 特定のメソッドを指定した@Beforeと@After
- 特定の修飾子を指定した@Beforeと@After
- springでAOPを使うための各種xmlファイルの設定
特定のパッケージを指定した@Beforeと@After
パッケージ「com.example.service.impl」配下の全クラスの全メソッドが対象となります。
パッケージ「com.example.service.impl」配下のサブクラスは対象外です。
@Aspect
@Component
public class ExampleAspect {
@Before("execution(* com.example.service.impl.*.*(..))")
public void before() {
System.out.println("このログは、メソッド処理「前」に実行しています。");
}
@After("execution(* com.example.service.impl.*.*(..))")
public void after() {
System.out.println("このログは、メソッド処理「後」に実行しています。");
}
}
特定のパッケージ配下(サブクラスを含)全てを指定した@Beforeと@After
パッケージ「com.example.service.impl」配下の全クラスの全メソッドが対象となります。
パッケージ「com.example.service.impl」配下のサブクラスの全クラスの全メソッドが対象となります。
@Aspect
@Component
public class ExampleAspect {
@Before("execution(* com.example..*.*(..))")
public void before() {
System.out.println("このログは、メソッド処理「前」に実行しています。");
}
@After("execution(* com.example..*.*(..))")
public void after() {
System.out.println("このログは、メソッド処理「後」に実行しています。");
}
}
特定のクラスを指定した@Beforeと@After
クラス「com.example.service.impl.ExampleServoceImpl」の全メソッドが対象となります。
@Aspect
@Component
public class ExampleAspect {
@Before("execution(* com.example.service.impl.ExampleServoceImpl.*(..))")
public void before() {
System.out.println("このログは、メソッド処理「前」に実行しています。");
}
@After("execution(* com.example.service.impl.ExampleServoceImpl.*(..))")
public void after() {
System.out.println("このログは、メソッド処理「後」に実行しています。");
}
}
特定のメソッドを指定した@Beforeと@After
クラス「com.example.service.impl.ExampleServoceImpl」の「find」メソッドが対象となります。
@Aspect
@Component
public class ExampleAspect {
@Before("execution(* com.example.service.impl.ExampleServoceImpl.find(..))")
public void before() {
System.out.println("このログは、メソッド処理「前」に実行しています。");
}
@After("execution(* com.example.service.impl.ExampleServoceImpl.find(..))")
public void after() {
System.out.println("このログは、メソッド処理「後」に実行しています。");
}
}
特定の修飾子を指定した@Beforeと@After
パッケージ「com.example.service.impl」配下の全クラスのpublicメソッドが対象となります。
パッケージ「com.example.service.impl」配下のサブクラスの全クラスのpublicメソッドが対象となります。
@Aspect
@Component
public class ExampleAspect {
@Before("execution(public * com.example..*.*(..))")
public void before() {
System.out.println("このログは、メソッド処理「前」に実行しています。");
}
@After("execution(public * com.example..*.*(..))")
public void after() {
System.out.println("このログは、メソッド処理「後」に実行しています。");
}
}
springでAOPを使うための各種xmlファイルの設定
AOPを使うために、springの設定ファイル(servlet-context.xml)とmavenの設定ファイル(pom.xml)へ設定を追加します。
※mavenの設定ファイル(pom.xml)は依存ライブラリをmavenで管理している場合のみに限ります。
servlet-context.xmlの設定
マーカーのついている部分をservlet-context.xmlへ追加して下さい。
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
・
・
<!-- AOPを使用するため以下を追加します。 -->
<aop:aspectj-autoproxy/>
・
・
</beans:beans>
pom.xmlへ設定
cglibは、spring-aopの依存ライブラリなので追加する必要があります。
・
・
<dependencies>
<!-- aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
・
・
最後に
@Before、@Afterをどこで動かすかについては「execution」で制御することが可能です。@Before、@Afterの使いどころは、「execution」の使い方をしっかりと押さえておけばOKです。
@Before、@Afterのサンプルでしたが、例外発生時やメソッド前後にも同じようにAspectjで処理をインジェクション出来るアノテーションが存在します。また@Before、@Afterでも通常のメソッド同様引数を受け取ることが出来ます。(これが出来ないとあまり役にたたないですよね。)
次回はこの辺りについてサンプルソースを作っていきたいと思います。