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) {
    ...
  }
これからもあんまり使わなさそう。