Aspect Oriented Programming with Spring

Reading Time: 4 minutes

What is AOP?

Applications are generally developed with multiple layers. A typical Java application has

  • Web Layer – Exposing the services to the outside world using REST or a web application
  • Business Layer – Business Logic
  • Data Layer – Persistence Logic

While the responsibilities of each of these layers are different, there are a few common aspects that apply to all layers

  • Logging
  • Security

These common aspects are called Cross Cutting Concerns.

One option of implementing cross cutting concerns is to implement it separately in every layer. However, that would mean that the code becomes difficult to maintain.

Aspect-Oriented Programming (AOP) is a programming paradigm that complements Object-Oriented Programming (OOP) by separating concerns of a software application to improve modularization. The separation of concerns (SoC) aims for making software easier to maintain by grouping features and behavior into manageable parts which all have a specific purpose and business to take care of.

Aspect Oriented Programming Core Concepts

Before we dive into the implementation of Spring AOP implementation, we should understand the core concepts of AOP.

  1. Aspect: An aspect is a class that implements enterprise application concerns that cut across multiple classes, such as transaction management. Aspects can be a normal class configured through Spring XML configuration or we can use Spring AspectJ integration to define a class as Aspect using @Aspect annotation.
  2. Join Point: A join point is a specific point in the application such as method execution, exception handling, changing object variable values, etc. In Spring AOP a join point is always the execution of a method.
  3. Advice: Advices are actions taken for a particular join point. In terms of programming, they are methods that get executed when a certain join point with matching pointcut is reached in the application.
  4. Pointcut: Pointcut is expressions that are matched with join points to determine whether advice needs to be executed or not. Pointcut uses different kinds of expressions that are matched with the join points and the Spring framework uses the AspectJ pointcut expression language.
  5. Target Object: They are the object on which advices are applied. Spring AOP is implemented using runtime proxies so this object is always a proxied object. What is means is that a subclass is created at runtime where the target method is overridden and advice are included based on their configuration.
  6. AOP proxy: Spring AOP implementation uses JDK dynamic proxy to create the Proxy classes with target classes and advice invocations, these are called AOP proxy classes.

AOP Advice Types:

Based on the execution strategy of advice, they are of the following types.

  1. Before Advice: These advices runs before the execution of join point methods. We can use @Before annotation to mark an advice type as Before advice.
  2. After (finally) Advice: An advice that gets executed after the join point method finishes executing, whether normally or by throwing an exception. We can create after advice using @After annotation.
  3. After Returning Advice: Sometimes we want advice methods to execute only if the join point method executes normally. We can use @AfterReturning annotation to mark a method as after returning advice.
  4. After Throwing Advice: This advice gets executed only when join point method throws exception, we can use it to rollback the transaction. We use @AfterThrowing annotation for this type of advice.
  5. Around Advice: This is the most important and powerful advice. This advice surrounds the join point method and we can also choose whether to execute the join point method or not. We can write advice code that gets executed before and after the execution of the join point method. It is the responsibility of around advice to invoke the join point method and return values if the method is returning something. We use @Around annotation to create around advice methods.

Maven dependency to import in pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Let’s create our custom aspect to intercept execution of every method inside controller

@Aspect
@Component
@Slf4j
public class CustomAspect {

    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void controller() {
    }

    @Pointcut("execution(* *.*(..))")
    protected void allMethod() {
    }

    @Before("controller() && allMethod() && args(..,request)")
    public void logBefore(JoinPoint joinPoint, HttpServletRequest request) {
        log.info("Request received for method: " + joinPoint.getSignature().getName());
    }

    @AfterReturning(pointcut = "controller() && allMethod()", returning = "result")
    public void logAfter(JoinPoint joinPoint, Object result) {
        log.debug("Method Return value : " + result);
    }

    @AfterThrowing(pointcut = "controller() && allMethod()", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {
        log.error("An exception has been thrown in " + joinPoint.getSignature().getName() + " ()");
        log.error("Cause : " + exception.getCause());
    }

    //Around advice code that gets executed before and after the execution of the join point method
    @Around("controller() && allMethod()")
    public Object aroundControllerMethod(ProceedingJoinPoint jointPoint) throws Throwable {

        // Stuff we want to be executed before the actual method call
        final long start = System.currentTimeMillis();
        Object proceed = jointPoint.proceed();
        // Stuff we want to be executed after the actual method call
        final long executionTime = System.currentTimeMillis() - start;
        log.info("Time taken for execution: " + executionTime);
       return proceed;

    }
}

In the above code, we have seen how can we use different kinds of advice as per our requirements. Aspect oriented programming isn’t an independent style of programming. You can use Aspect Oriented programming in combination with functional programming, but also in combination with Object oriented one.

I hope, you have liked my blog. If you have any doubt or any suggestions to make please drop a comment.
Thanks!

References:
Spring aop official doc
Spring aop request response blog

knoldus-blog-footer-banner

Written by 

Vinisha Sharma is a software consultant having more than 6 months of experience. She thrives in a fast pace environment and loves exploring new technologies. She has experience with the languages such as C, C++, Java, Scala and is currently working on Java 8. Her hobbies include sketching and dancing. She believes Optimism and a learning attitude is the key to achieve success in your life

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading