Spring Boot AOP Other Implementations

Spring Boot AOP Other Implementations

In this article, I am going to discuss Spring Boot AOP Other Implementations. Please read our previous article where we discussed Spring Boot AOP Before Implementation.

Spring Boot AOP Other Implementations

In the previous article, we implemented the before AOP aspect. Here we shall implement the following aspects:

  • After Advice
  • Around Advice
  • Returning Advice
  • Throwing Advice

Step 1: Open the project from the previous project in VS Code. The file structure must be as follows:

Spring Boot AOP Other Implementations

Step 2: Modify FruitServiceAspect.java class to add the After Advice aspect:

Spring Boot AOP Other Implementations

This method shall execute after the advice has been sent.

Step 3: Modify FruitServiceAspect.java class to add the Around Advice aspect:

Spring Boot AOP Other Implementations

This method shall execute when the advice is being sent, i.e., when the getFruits() method is executing.

Step 4: Modify the FruitServiceAspect.java class to add the After Returning Advice aspect:

Spring Boot AOP Other Implementations

This method shall execute after the getFruits() method finishes execution.

Step 5: Modify the FruitServiceAspect.java class to add the After Throwing Advice aspect:

Spring Boot AOP Other Implementations

This method shall execute when the getFruits() method throws an error.

Step 6: Compile and execute the application. Ensure compilation is successful:

Spring Boot AOP Other Implementations

Step 7: Go to the webpage http://localhost:8080/view-products from your browser. The following output must be visible:

Spring Boot AOP Other Implementations

In the VS Code terminal, the following output must be visible:

Spring Boot AOP Other Implementations

We can see from the output that all the functions execute, except for the afterThrowing() method. As mentioned above, the afterThrowing() method executes only when the getFruits() throws an exception. In this case, getFruits() does not throw an exception. Congratulations! You now know how to implement AOP in Spring Boot!

The Complete Example Code: 
Fruits.java – The POJO class
package com.dotnet.restful;

public class Fruits {
    private String id;
    private String name;
 
    public String getId()               {return id;}
    public void setId(String id)        {this.id = id;}
    public String getName()             {return name;}
    public void setName(String name)    {this.name = name;}

    public Fruits (String nid, String nname)
    {
        id = nid;
        name = nname;
    }
 }
FruitService.java – The class responsible for handling the CRUD operations.
package com.dotnet.restful;

import java.util.Collection;

public interface FruitService
{
    public abstract void createFruit (Fruits fruits);
    public abstract void updateFruit (String id, Fruits fruits);
    public abstract void deleteFruit (String id);
    public abstract Collection<Fruits> getFruits();
}
FruitServiceAspect.java – The file containing the AOP code.
package com.dotnet.restful;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class FruitServiceAspect
{
    //Before AOP for getFruits();
    @Before(value = "execution(* com.dotnet.restful.FruitService.*(..)) and args()")
    public void beforeAdvice(JoinPoint joinPoint)
    {
        System.out.println("Before advice: " + joinPoint.getSignature());
    }

    @After(value = "execution(* com.dotnet.restful.FruitService.*(..)) and args()")
    public void afterAdvice(JoinPoint joinPoint)
    {
        System.out.println("After method: " + joinPoint.getSignature());
    }

    @Around(value = "execution(* com.dotnet.restful.FruitService.*(..)) and args()")
    public void aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable
    {
        System.out.println("Around advice (before invoking method): " + joinPoint.getSignature().getName());
        try
        {
            joinPoint.proceed();
        }
        finally
        {

        }
        System.out.println("Around advice (after invoking method): " + joinPoint.getSignature().getName());
    }

    @AfterReturning(value = "execution(* com.dotnet.restful.FruitService.*(..))", returning = "fruits")
    public void afterReturningAdvice(JoinPoint joinPoint)
    {
        System.out.println("After returning method: " + joinPoint.getSignature());
    }

    @AfterThrowing(value = "execution(* com.dotnet.restful.FruitService.*(..))", throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex)
    {
        System.out.println("After throwing exception in method: " + joinPoint.getSignature());
        System.out.println("The exception is: " + ex.getMessage());
    }
}
FruitServiceController.java – The class responsible for providing the REST API.
package com.dotnet.restful;

import org.springframework.beans.factory.annotation.Autowired;
//Required web classes
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FruitServiceController
{
   @Autowired
   FruitService fruitService;

   @RequestMapping(value = "/products")
   public ResponseEntity<Object> getProduct() {
      return new ResponseEntity<>(fruitService.getFruits(), HttpStatus.OK);
   }

   @RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
   public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Fruits fruits)
   { 
      fruitService.updateFruit(id, fruits);
      return new ResponseEntity<>("Fruit is updated!", HttpStatus.OK);
   }
   
   @RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
   public ResponseEntity<Object> delete(@PathVariable("id") String id)
   {
      fruitService.deleteFruit(id);
      return new ResponseEntity<>("Fruit is deleted!", HttpStatus.OK);
   }
   
   @RequestMapping(value = "/products", method = RequestMethod.POST)
   public ResponseEntity<Object> createProduct(@RequestBody Fruits product)
   {
      fruitService.createFruit(product);
      return new ResponseEntity<>("Fruit is created!", HttpStatus.CREATED);
   }
}
FruitServiceImpl.java – The class in which the CRUD operations occur.
package com.dotnet.restful;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

@Service
public class FruitServiceImpl implements FruitService
{
    private static Map<String,Fruits> database = new HashMap<>();
    static {
        Fruits apple = new Fruits("1","Apple");
        database.put(apple.getId(), apple);
  
        Fruits banana = new Fruits("2","Banana");
        database.put(banana.getId(), banana);
  
        Fruits chiku = new Fruits("3","Chiku");
        database.put(chiku.getId(), chiku);
  
        Fruits dragon = new Fruits("4","Dragon Fruit");
        database.put(dragon.getId(), dragon);
     }

    @Override
    public void createFruit(Fruits fruits)  {database.put(fruits.getId(), fruits);}
    @Override
    public void deleteFruit(String id)      {database.remove(id);}
    @Override
    public Collection<Fruits> getFruits()   {return database.values();}

    @Override
    public void updateFruit(String id, Fruits fruits)
    {
        database.remove(id);
        fruits.setId(id);
        database.put(id, fruits);
    }
}
RestfulApplication.java – The class containing the main() function.
package com.dotnet.restful;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class RestfulApplication {

    public static void main(String[] args) {
        SpringApplication.run(RestfulApplication.class, args);
    }

    @Bean
    public RestTemplate getRestTemplate ()
    {
        return new RestTemplate();
    }
}
WebController.java – The class responsible for providing web services.
package com.dotnet.restful;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WebController
{
    @RequestMapping(value = "/view-products")
    public String viewProducts()    {return "view-products";}

    @RequestMapping(value = "/add-products")
    public String addProducts()    {return "add-products";}
}
add-products.html
<!DOCTYPE html>
<html>
   <head>
      <title>Add Products</title>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
      
      <script>
         $(document).ready(function() {
            $("button").click(function() {
               var productmodel = {
                  id : "5",
                  name : "Fig"
               };
               var requestJSON = JSON.stringify(productmodel);
               $.ajax({
                  type : "POST",
                  url : "http://localhost:8080/products",
                  headers : {
                     "Content-Type" : "application/json"
                  },
                  data : requestJSON,
                  success : function(data) {
                     alert(data);
                  },
                  error : function(data) {
                  }
               });
            });
         });
      </script>
   </head>
   
   <body>
      <button>Click here to submit the form</button>
   </body>
</html>
view-products.html
<!DOCTYPE html>
<html>
   <head>
      <title>View Products</title>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

      <script>
         $(document).ready(function(){
            $.getJSON("http://localhost:8080/products", function(result){
               $.each(result, function(key,value) {
                  $("#productsJson").append(value.id+" "+value.name+" ");
               }); 
            });
         });
      </script>
   </head>
   
   <body>
        <h1>Fruits: </h1>
        <div id = "productsJson"> </div>
   </body>
</html>

In the next article, I am going to discuss Introduction to Spring Boot JPA. Here, in this article, I try to explain Spring Boot AOP Other Implementations with Examples. I hope you enjoy this Spring Boot AOP Other Implementations article.

Leave a Reply

Your email address will not be published. Required fields are marked *