4 Kasım 2018 Pazar

SpringAOP @Before Anotasyonu

Giriş
Pointcut ile belirtilen metoddan önce bir kod çalıştırmak içindir. Açıklaması şöyle.
Before advice: Advice that executes before a join point, but which does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception). 
Örnek
Şöyle yaparız.
@Before("mypointcut()")
public void beforeControllerCall(JoinPoint joinPoint) {
  ...
}
Bu metodlardan exception fırlatılırsa global bir yerde yakalamak için  @ExceptionHandler Anotasyonu kullanılır.

Örnek - JoinPoint  içindeki metod ismine ve parametrelerine erişmek
Şöyle yaparız. Burada özel bir @Pointcut tanımlanmıyor. @Before advice içine @LogMethod anotasyonuna sahip metodlar tanımlanıyor.
@Aspect
@Component
public class LoggingAspect {

  @Before("@annotation(LogMethod)")
  public void logMethodName(JoinPoint joinPoint) {
    String method = joinPoint.getSignature().getName();
    String params = Arrays.toString(joinPoint.getArgs());
    System.out.println("Method [" + method + "] gets called with parameters " + params);
  }
}
Örnek - JoinPoint  içindeki metod parametrelerine erişmek
Elimizde şöyle bir kod olsun. Burada JoinPoint.getArgs() ile metod parametrelerine erişiliyor.
@Component
public class AopUtils {

  public <T> Optional<T> getParamByType(JoinPoint joinPoint, Class<T> paramClass) {
    for (Object parameter : joinPoint.getArgs()) {
      if (paramClass.isInstance(parameter)) {
        return Optional.of((T) parameter);
      }
    }
    return Optional.empty();
  }
}
Şöyle yaparız
@Aspect
@Component
@Slf4j
public class TraceAccessDetailsAspect {

  private final AopUtils aopUtils;

  public TraceAccessDetailsAspect(AopUtils aopUtils) {
    this.aopUtils = aopUtils;
  }

  @Before("methodAnnotatedWithTraceAccessDetails()")
  public void logAccessDetails(JoinPoint joinPoint) {
    ContextInformation contextInformation = aopUtils.getParamByType(joinPoint,
ContextInformation.class).orElseThrow();
    Long resourceId = aopUtils.getParamByType(joinPoint, Long.class).orElseThrow();

    log.info("User [{}] accessing resource [{}] at [{}]", contextInformation.getUserId(),
resourceId,LocalTime.now());
  }

  @Pointcut("execution(@io.controller.aop.annotation.TraceAccessDetails * *(..))")
  public void methodAnnotatedWithTraceAccessDetails() {
  }
}
Diğer
Bu anotasyon yerine eskiden şöyle yapılırdı.
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;


public class SecurityAdvice implements MethodBeforeAdvice {

  @Override
  public void before(Method method, Object[] args, Object target) throws Throwable {
    ...
  }
}


Hiç yorum yok:

Yorum Gönder