3 Şubat 2020 Pazartesi

SpringAOP @Pointcut Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.aspectj.lang.annotation.Pointcut;
Hangi kodlar için pointcut oluşacağını belirtir. Pointcut için @Before, @After,@Around kodları işletilir.

@annotation Kullanımı
Belirtilen anostasyona sahip metodlar için pointcut oluşturur.
Örnek - @Before ile Pointcut
Şöyle yaparız. @Point anotasyonuna sahip metod ismi, @Before içinde kullanılır
@Aspect
public class AuthorizationAspect {
  @Pointcut("@annotation(AuthenticateAccount)")
  public void authorized() {}

  private boolean isAuthorized() {
    // logic to check is user is authorised to call the api
  }

  @Before("authorized()")
  public void beforeControllerCall(JoinPoint joinPoint) throws UnauthorizedException {

    if(!isAuthorized)) {
      throw new UnauthorizedException("You don't have rights over this API");
    }

  }
}
Örnek - @Around ile Pointcut
Şöyle yaparız
@Aspect
public class LoggableAspect {
  
  @Pointcut("@annotation(com.vishnu.service.TrackTime)")
  public void executeTiming(){}

  @Around("executeTiming()")
  public Object logMethodTiming(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
    long startTime = System.currentTimeMillis();
    Object returnValue = proceedingJoinPoint.proceed();
    long totalTime = System.currentTimeMillis() - startTime;
    log.info("Time Taken by service '{}' is {} ms",alo
proceedingJoinPoint.getSignature().getName(), totalTime);
    return returnValue;
  }
execution Kullanımı
İsmi belirtilen metodlar için pointcut oluşturur.

Örnek - Tüm modifier'lara sahip sadece paket ismi belirtilen tüm metodlar
Şöyle yaparız.
execution(* com.foo.bar.data.*.*(..))
Örnek - public ve ismi kısmen belirtilen metodlar
Elimizde şöyle bir kod olsun
class Service {

  @Transactional
  public void serviceA(){
    // do something
    
  }

  @Transactional
  public void serviceB(){
    // do something
  }
}
İsmi service kelimesi ile başlayan public metodlar için şöyle yaparız. @Around kullanımında pointcut belirtilir.
@Aspect
class ServiceAspect {

  @Pointcut("execution(public * service*)")
  private void fooAspect(){...};

  @Around("fooAspect()")
  public Object fooAround(ProceedingJoinPoint joinPoint) throws Throwable {
    ...
  }

}
Örnek - Sadece public olan tüm metodlar
Şöyle yaparız.
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DataSourcePickerAspect implements Ordered {

  private int order;

  @Value("10")
  public void setOrder(int order) {
    this.order = order;
  }

  @Override
  public int getOrder() {
    return order;
  }

  @Pointcut(value="execution(public * *(..))")
  public void anyPublicMethod() { }


  @Around("@annotation(dataSourcePicker)")
  public Object pickDataSource(ProceedingJoinPoint pjp, 
    DataSourcePicker dataSourcePicker) throws Throwable {
    //some code...
  }
}  
Örnek - İsmi Belirtilen Sınıftaki Tüm Metodlar
Şöyle yaparız. serviceMethods() ismi belirtilen sınıftaki tüm metodları seçer.
@Aspect
@Slf4j
public class LoggingAspect {

@Pointcut("execution(* com.tlc.tracker.v01.controller.*.*(..))")
public void controllerMethods() { }

@Pointcut("execution(* com.tlc.tracker.v01.service.imp.ProjectServiceImpl.*(..))")
public void serviceMethods(){  }

@Pointcut("execution(* com.tlc.tracker.v01.repository.*.*(..))")
public void respositoryMethods(){  }

@Before("serviceMethods()")
public void Areturn(JoinPoint point){
    System.out.println("Hola");
    log.info("HOLA");
}

@AfterThrowing(pointcut = "controllerMethods() && serviceMethods() &&
  respositoryMethods()", throwing = "exception")
public void logAfterThrowing(JoinPoint joinPoint, Throwable exception){
  ...
}

within Kullanımı
Örnek ver

Hiç yorum yok:

Yorum Gönder