SpringAOP etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
SpringAOP etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

4 Temmuz 2023 Salı

SpringAOP PerformanceMonitorInterceptor Sınıfı

Giriş
Şu satırı dahil ederiz
import org.springframework.aop.interceptor.PerformanceMonitorInterceptor;
Açıklaması şöyle
When you enable the “PerformanceMonitorInterceptor,” it quietly observes your code and collects essential information, such as the execution time of different methods. It keeps a record of how much time is spent in each method, which is incredibly helpful in identifying bottlenecks or areas where your code might be slowing down.

Having access to this information allows you to analyze and optimize your code to make it faster and more efficient. For example, if you discover that a particular method is taking too much time to execute, you can focus on optimizing that specific part of your code to improve overall performance.

Moreover, the “PerformanceMonitorInterceptor” enables you to measure the performance of your code across multiple requests or interactions. This broader perspective helps you understand how your application is performing over time, rather than relying on isolated measurements.
Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

AbstractMonitoringInterceptor sınıfından kalıtır. Loglama ayarları için şöyle yaparız
logging.level.dev.knowledgecafe=TRACE
logging.level.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE

Örnek
Şöyle yaparız
@Configuration
@EnableAspectJAutoProxy
public class AopConfiguration {
  @Pointcut("execution(public String foo.EmployeeService.getFullName(..)))")
  public void monitor() { }

  @Bean
  public PerformanceMonitorInterceptor performanceMonitorInterceptor() {
    return new PerformanceMonitorInterceptor(true);
  }

  @Bean
  public Advisor performanceMonitorAdvisor() {
    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    pointcut.setExpression("dev.knowledgecafe.performance_trace.AopConfiguration.monitor()");
    return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
  }
}

24 Kasım 2022 Perşembe

SpringAOP AopUtils Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.springframework.aop.support.AopUtils;
isAopProxy metodu
Belirtilen nesne JDK dynamic proxy veya CGLIB proxy ise true döner

Örnek
Şöyle yaparız. Burada BatteryRepository bir JpaRepository nesnesi. Sonuç true olacaktır
@Autowired
private BatteryRepository batteryRepository;

@Test
void testBatteryServiceIsProxy() {
  boolean isProxy = AopUtils.isAopProxy(batteryRepository);
  Assertions.assertTrue(isProxy);
}

27 Ocak 2021 Çarşamba

SpringAOP Kullanımı

Giriş
SpringAOP Kavramları yazısına bakabilirsiniz.

Maven
Şu satırı dahil ederiz.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Spring ile Aspect Oriented Programlama Yapmak için iki seçenek var.
1. Spring AOP
2. AspectJ. AspectJ varsayılan yöntem değil, çünkü yavaş. Açıklaması şöyle.
AspectJ is a runtime resolution, which has a performance drawback.
AspectJ için şu satırı dahil ederiz
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
</dependency>
Spring AOP
SpringAOP sadece bean'ler üzerinde kullanılabilir. Açıklaması şöyle.
Spring AOP runs everything through proxies which sadly can't be everywhere.
....
Proxies are created only for singletons (@Bean) so we are greatly limited when we want to secure methods on specific objects (such as JPA @Entities) that are not beans. Proxies also won't be called within calling objects (bean calling its methods in context of self - this).
Kullanım
1. Bir @Aspect sınıfı oluşturulur. Bu sınıfın Spring ayağa kalkarken bulunuyor olması gerekir.
2. Bu sınıf içinde @Pointcut ile hangi metodların seçileceği belirtilir.
3. Daha sonra Advice ile Pointcut birbirlerine sağlanır. Temel olarak 3 çeşit advice vardır. Bunlar şöyle
- @Before Advice 
- @After Advice
- @Around Advice

@AfterThrowing de bir advice'tır ancak temel kullanıma dahil etmedim.

@Before ile @Pointcut ile seçilen metodlardan önce kod çalıştırılabilir. @Before Anotasyonu yazısına bakabilirsiniz.

@After ile @Pointcut ile seçilen metodlardan sonra kod çalıştırılabilir. @After Anotasyonu yazısına bakabilirsiniz.

@Around ile @Pointcut ile seçilen metodlardan önce ve sonra kod çalıştırılabilir. 

6. @AfterThrowing ile @Pointcut ile seçilen metodlardan exception fırlatılınca kod çalıştırılabilir. 

Örnek
Şö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
Şöyle yaparız. Burada 3 tane @Pointcut var ve metodların için boş. 
- Daha sonra @Before advice ile pointcut bağlanıyor
- @AfterThrowing advice ile pointcut bağlanıyor
@Aspect
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){

  if(exception instanceof BusinessServiceException){
    //Get the parts of the exception message
    String exceptions[] = exception.getMessage().split(":", 2);
    //Get the message contained in the exception message
    String message = exceptions.length == 1 ? "" : exceptions[1];

    log.error("[" + joinPoint.getSignature().getName() 
      + "] - Type: " + exceptions[0] + ". Message: "+ message);
  }

  if(exception instanceof Exception){
    log.error("[" + joinPoint.getSignature().getName()
      + "] - Type: ServerError. Message: "  + exception.getMessage());
  }
}

11 Ağustos 2020 Salı

SpringAOP RequestBodyAdvice Arayüzü

Örnek
Şöyle yaparız
@ControllerAdvice
public class CustomRequestBodyAdvice implements RequestBodyAdvice {

  @Override
  public boolean supports(MethodParameter methodParameter, Type targetType,
 Class<? extends HttpMessageConverter<?>> converterType) {
    
    return methodParameter.getContainingClass() == QuestionController.class &&
 targetType.getTypeName() == Question.class.getTypeName();
  }

  @Override
  public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage,
    MethodParameter parameter, Type targetType,
    Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
    System.out.println("In beforeBodyRead() method of " + getClass().getSimpleName());
    return inputMessage;
  }

  @Override
  public Object afterBodyRead(Object body, HttpInputMessage inputMessage,
 MethodParameter parameter, Type targetType,
    Class<? extends HttpMessageConverter<?>> converterType) {
    
    if (body instanceof Question) {
      Question question = (Question) body;
      question.setDate(new Date());
      return question;
    }

    return body;
  }

  @Override
  public Object handleEmptyBody(Object body, HttpInputMessage inputMessage,
 MethodParameter parameter, Type targetType,
    Class<? extends HttpMessageConverter<?>> converterType) {
    
    return body;
  }
}