<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beugré Toussaint</title>
    <description>The latest articles on DEV Community by Beugré Toussaint (@tuxbedev).</description>
    <link>https://dev.to/tuxbedev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F777925%2F6de91a6c-f03a-4beb-a0d0-967d080d7a76.jpg</url>
      <title>DEV Community: Beugré Toussaint</title>
      <link>https://dev.to/tuxbedev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tuxbedev"/>
    <language>en</language>
    <item>
      <title>Spring AOP pour la journalisation</title>
      <dc:creator>Beugré Toussaint</dc:creator>
      <pubDate>Tue, 22 Oct 2024 11:04:29 +0000</pubDate>
      <link>https://dev.to/tuxbedev/spring-aop-pour-la-journalisation-3gk</link>
      <guid>https://dev.to/tuxbedev/spring-aop-pour-la-journalisation-3gk</guid>
      <description>&lt;p&gt;AOP (Aspect Oriented programming) est un paradigme de programmation qui permet la séparation du code métier du code technique. Ce paradigme est un peu délaissé par bon nombre de développeurs mais constitue un très puissant outil.&lt;br&gt;
Dans ce tutoriel, nous essaierons d'appliquer ce paradigme dans la journalisation de nos services avec spring boot 3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pré-requis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JDK 17&lt;/li&gt;
&lt;li&gt;IDE&lt;/li&gt;
&lt;li&gt;maven 3.x&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dépendences à ajouter&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-aop&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;3.2.3&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.projectlombok&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;lombok&amp;lt;/artifactId&amp;gt;
            &amp;lt;optional&amp;gt;true&amp;lt;/optional&amp;gt;
        &amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LoggingAspect.java&lt;/strong&gt;&lt;br&gt;
 Cette class contiendra notre AOP pour la journalisation :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package dev.tuxbe.democonfig.contracts;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
@Slf4j
public class LoggingAspect {

    @Pointcut("execution(* dev.tuxbe.democonfig.services.*.*(..))")
    public void serviceMethods() {
    }

    @Before("serviceMethods()")
    public void logBeforeServiceMethods(JoinPoint joinpoint) {
        String name = joinpoint.getSignature().getName();
        log.info("Début de traitement de la method {} avec pour parametre {}", name, joinpoint.getArgs());
    }

    @AfterReturning(value = "serviceMethods()", returning = "proceed")
    public void logAfterReturningServiceMethods(JoinPoint joinpoint, Object proceed) {
        String methodName = joinpoint.getSignature().getName();
        Object[] args = joinpoint.getArgs();

        // Logiquement, si nous atteignons ce point, le traitement s'est bien terminé
        log.info("Méthode {} exécutée avec succès avec les arguments {}", methodName, args);
        log.info("Résultat : {}", proceed);
    }

    @AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
    public void logAfterThrowingServiceMethods(JoinPoint joinPoint, Throwable ex) {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();

        // Récupérer la requête HTTP
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String uri = request.getRequestURI();
        String method = request.getMethod();

        // Logiquement, si nous atteignons ce point, une exception a été levée pendant l'exécution de la méthode
        log.info("{} : {} exécutée avec echec avec les arguments {}",method, uri, args);
        log.info("Message d'error : {}", ex.getMessage());
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;@Pointcut()&lt;/strong&gt; permet de marquer un point d'écoute à chaque fois qu'une méthode se trouvant dans le package &lt;strong&gt;dev.tuxbe.democonfig.services&lt;/strong&gt; est appelée.&lt;/li&gt;
&lt;li&gt;La méthode annoté avec &lt;strong&gt;@Before("serviceMethods()")&lt;/strong&gt; est appelé avant l’exécution des services que vous écoutez&lt;/li&gt;
&lt;li&gt;La méthode annoté avec &lt;strong&gt;AfterThrowing()&lt;/strong&gt; est exécutée à chaque fois qu'une erreur sera détectée lors de l’exécution du service écouté.&lt;/li&gt;
&lt;li&gt;La méthode annoté avec &lt;strong&gt;AfterReturning()&lt;/strong&gt; est exécutée lorsque l'exécution du service s'est déroulée sans erreur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cette technique de journalisation  vous aide à avoir un code maintenable et propre 🚀&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>springaop</category>
    </item>
    <item>
      <title>Dépendances cycliques en spring boot</title>
      <dc:creator>Beugré Toussaint</dc:creator>
      <pubDate>Tue, 22 Oct 2024 10:23:14 +0000</pubDate>
      <link>https://dev.to/tuxbedev/dependances-cycliques-4np8</link>
      <guid>https://dev.to/tuxbedev/dependances-cycliques-4np8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdskwak2yzkxeqz194a5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdskwak2yzkxeqz194a5.png" alt="Dépendances cycliques entre deux classes" width="385" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Une dépendance cyclique intervient en Java lorsque deux class ou deux modules dépendent l'un de l'autre, formant ainsi un cycle.&lt;/p&gt;

&lt;p&gt;Supposons que nous ayons deux beans A et B qui dépendent l'un de l'autre comme le montre l'exemple ci-dessous :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class A{
    private final B b;
    public A(B b){
        this.b = b;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class B{
    private final A a;
    public B(A a){
        this.a = a;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lors de l'exécution de votre projet, vous aurez l'erreur suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ainsi, pour résoudre cette dépendance cyclique, nous avons quatre solutions : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoriser le code pour séparer les responsabilités.&lt;/li&gt;
&lt;li&gt;Utiliser des classes intermédiaires ou des interfaces.&lt;/li&gt;
&lt;li&gt;Appliquer l'injection de dépendances via des méthodes (setter).&lt;/li&gt;
&lt;li&gt;Utiliser des annotations comme &lt;a class="mentioned-user" href="https://dev.to/lazy"&gt;@lazy&lt;/a&gt; pour retarder l'initialisation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans notre cas, nous utiliserons la quatrième solution qui est juste d'utiliser l'annotation &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/lazy"&gt;@lazy&lt;/a&gt;&lt;/strong&gt; comme le montre l'exemple ci-dessous :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class A{
    private final B b;
    public A(@Lazy B b){
        this.b = b;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class B{
    private final A a;
    public B(A a){
        this.a = a;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voilà, nous sommes désormais sorti de ce cycle :)&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>java</category>
    </item>
  </channel>
</rss>
