SIer だけど技術やりたいブログ

SpringのAOP @Pointcutの使いどころ

Spring Java

SpringのAOP @Pointcutの使いどころ

SpringのAOPアノテーションで、@Pointcutだけ使い方がよくわからなかったのでメモ。

SpringのAOPってなに?

具体的な処理と関係のない処理(ロギングとか)が混じっていると、煩雑になって保守性が下がる。なので、具体的な処理と関係のない処理は別の場所でやりましょうね。という技術。

煩雑なコードの例

public class HogeClass {  
  private static final Logger logger = LoggerFactory.getLogger(HogeClass.class); 
  
  public void methodOne(String arg) {
    logger.info("methodOne start" + arg);
    //本当にやりたい処理が埋もれて見づらい
    ...
    logger.info("methodOne end" + arg);
  }
}

以下のようなクラスを作るとログ処理が挟み込める。(例だから適当)

@Aspect
public class LoggingAspects {

  @Around("execution(* methodOne(..))")
  public void logging(ProceedingJoinPoint pjp) throws Throwable{
    String methodName = pjp.getSignature().getName();
    Logger logger = LoggerFactory.getLogger(pjp.getTarget().getClass());
    logger.info(methodName + " start " + pjp.getArgs()[0]);
    pjp.proceed();
    logger.info(methodName  + " end " + pjp.getArgs()[0]);
  }
}
AOPのクラスかどうか@Aspect
どんなタイミングでメソッドを実行するか@Around ※1
どんな条件でメソッドを実行するかexecution(* methodOne(..)) ※2

※1 この他に@Before,@After,@AfterThrowing,@AfterReturingがある
※2 executionの他にannotation(..)でannotationがついてるかどうかでチェックできたりする。詳細はリファレンス参照。

本題(@Pointcutの使い道)

@Around(…)などで指定する条件式を使いまわしたいときに使う。

package common;

@Aspect
public class MyPointcuts {
  @Pointcut("execution(* methodOne(..))")
  public void methodOne(){}
@Aspect
public class LoggingAspects {

  @Around("common.MyPointcuts.methodOne()")
  public void logging(ProceedingJoinPoint pjp) {
    ...
  }

これからもあんまり使わなさそう。

参考

11. Aspect Oriented Programming with Spring