CodeGym /Courses /Module 5. Spring /Introduction to AOP (aspect-oriented programming)

Introduction to AOP (aspect-oriented programming)

Module 5. Spring
Level 3 , Lesson 0
Available

1. Core concepts of AOP

To avoid getting lost in acronyms, let's clarify the definitions.

Aspect-oriented programming (AOP) is a paradigm that lets you extract and encapsulate so-called "cross-cutting concerns".

What are "cross-cutting concerns"?

Imagine you have an app with a lot of modules. In each module you might need to log actions, manage transactions, or validate parameters. The logic for these tasks isn't part of the module's core business functionality — they're "cross-cutting concerns". It's smarter to centralize that code in one place so you don't duplicate it across modules and turn your architecture into a patchwork of repeated pieces.

Benefits of AOP:

  1. Modularity — you can isolate the logic of these concerns and apply it where needed.
  2. Cleaner code — less duplicated code in your business logic.
  3. Ease of changes — fixes in a cross-cutting concern automatically apply everywhere it's used.

AOP in real projects

Theory getting boring? Alright, let's move to real scenarios where AOP really shines:

  • Logging: automatic printing of method execution time, call parameters, and result.
  • Transactions: managing database transactions.
  • Security: checking user access rights.
  • Caching: you can automatically cache method results.
  • Error handling: centralized exception handling.

AOP helps simplify your code, letting you focus on business problems instead of boilerplate.


2. Key AOP concepts: Aspect, Pointcut, Advice

Getting to know AOP wouldn't be complete without three key concepts. Let's break them down with examples:

Aspect (Aspect)

An Aspect is a module that encapsulates the logic of cross-cutting concerns. For example, if you want to log method execution, you'd create a logging aspect.

Think of an aspect as an independent observer of your code. It only interferes when it's actually needed.

Example:


@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.*.*(..))") // Define where the aspect triggers
    public void logMethodCall() {
        System.out.println("Method called!");
    }
}

Pointcut (Pointcut)

A Pointcut is an expression that indicates where exactly (at which places) the aspect should "kick in". A pointcut highlights join points — spots in the code where you can add behavior via aspects.

You can think of pointcut syntax as a language to filter methods:

  • execution(* com.example.service.*.*(..)) — invoke the aspect for all methods in the service package.
  • execution(public * *(..)) — apply the aspect to all public methods.

Advice (Advice)

Advice is the code that defines "what" and "when" to run at a join point. There are five types of advice:

  • Before — action runs before the method.
  • After — action runs after the method.
  • AfterReturning — runs after the method successfully returns.
  • AfterThrowing — runs if the method threw an exception.
  • Around — you control the method execution (you can even cancel it!).

Example of advices:


@Aspect
@Component
public class DetailedLoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethodCall() {
        System.out.println("Before method call");
    }

    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void afterReturningFromMethod() {
        System.out.println("Method completed successfully");
    }

    @AfterThrowing("execution(* com.example.service.*.*(..))")
    public void afterExceptionThrown() {
        System.out.println("Method threw an exception!");
    }
}

We're done with advice details. Let's move to practice!


3. How AOP solves problems in your application

Logging

Typical situation: you have a bunch of methods, and you want to know when they run and with what parameters.


@Aspect
@Component
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object result = joinPoint.proceed();  // Method call

        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + " ms");

        return result;
    }
}

Transaction management

With an aspect it's easier to set up transactional behavior — the logic is separated from the main code:


@Component
@Aspect
public class TransactionAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Transaction started");
        Object result;
        try {
            result = joinPoint.proceed(); // Method call
            System.out.println("Transaction completed");
        } catch (Exception e) {
            System.out.println("Rolling back transaction due to error");
            throw e;
        }
        return result;
    }
}

Security

With AOP you can easily add access checks to methods:


@Aspect
@Component
public class SecurityAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void checkUserAccess() {
        // Pseudocode
        if (!userHasAccess()) {
            throw new SecurityException("Access denied!");
        }
    }
}

4. Integrating AOP into a Spring application

To work with AOP in Spring you need to include the spring-boot-starter-aop module. If you use Spring Boot, it's wired up automatically.

Example setup

  1. Make sure the spring-boot-starter-aop dependency is added to your pom.xml:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  1. Annotate aspects with @Aspect, and mark your cross-concern class with @Component.

5. Why this matters in real projects

AOP removes endless copy-paste of utility code across the system. Imagine you have dozens of microservices and you want to change the logging logic. Without AOP you'd have to dive into each service and change it manually — that costs time and introduces risk. AOP lets you extract that functionality into one place and manage it centrally.

On interviews, knowledge of AOP shows you understand architectural approaches. Moreover, being able to explain how aspects simplify code maintenance makes you a strong candidate.

Ready to go further? In the next lectures we'll dive into the intricacies of Pointcut and customizing aspects! See you in the next method! 😄

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION