Şuayb's BlogŞuayb's Blog
Home
Categories
Games
MediumAboutContact
Language
Theme
    1. Blog
    2. Programming
    3. Aspect-Oriented Programming in Spring Boot

Aspect-Oriented Programming in Spring Boot

PublishedDecember 18, 2024
UpdatedDecember 19, 2024
Reading time3 min read
JavaKotlinSpring BootAOP
XLinkedInFacebook
Aspect-Oriented Programming in Spring Boot

Loading likes...

Aspect-Oriented Programming (AOP) provides a way to modularize cross-cutting concerns, such as logging, transaction management, and security. This guide demonstrates how to implement AOP in Spring Boot with examples in Java and Kotlin.


Last updatedDecember 19, 2024

Total viewsLoading hits...

Previous articleDependency Injection in Spring BootNext articleSpring Boot Actuator
Şuayb Şimşek

Written by

Şuayb Şimşek

Backend-focused fullstack developer sharing practical notes on Spring Boot, security, microservices, and cloud-native architecture.

Expertise

  • Spring Boot
  • Go
  • Microservices
  • Next.js
  • Cloud Native

Connect

GitHubLinkedInMedium

Related posts

Spring Boot Configuration Properties
Programming

Spring Boot Configuration Properties

Learn how to use @ConfigurationProperties for type-safe configuration, validate settings with @Validated, and manage environment-specific values with profile-specific application-{profile}.yml files.

February 4, 20263 min read
JavaKotlinSpring BootConfiguration
Spring Boot GraphQL JWE Authentication
Programming

Spring Boot GraphQL JWE Authentication

Learn how to secure your Spring Boot GraphQL APIs with stateless encrypted JWTs (JWE) while persisting user identities and roles in a JPA-backed database.

May 17, 20256 min read
JavaKotlinSpring BootSecurityJWTJWEGraphQL
Spring Boot JWE Authentication with JPA
Programming

Spring Boot JWE Authentication with JPA

Learn how to use stateless encrypted JWTs (JWE) to secure your Spring Boot APIs while persisting user identities and roles in a JPA-backed database.

May 11, 20254 min read
JavaKotlinSpring BootSecurityJWTJWEJPA

About

Articles on Spring Boot, microservices, security, and more.

ContactStart here

Latest posts

  • Captain Tsubasa 2: World Fighters
  • Captain Tsubasa: Rise of New Champions
  • Spring Boot Configuration Properties
  • Spring Boot GraphQL JWE Authentication
  • Spring Boot JWE Authentication with JPA

Top topics

JavaKotlinSpring BootJWEJWTMicroservice

Subscribe

Get practical backend + fullstack notes when new articles are published.

Social

© 2024-2026 Şuayb's Blog. All rights reserved.

🌟 Why Use AOP?

AOP enables developers to separate concerns that affect multiple parts of an application, like logging or security, into reusable aspects. This approach promotes cleaner code, improved maintainability, and reduced redundancy.


📋 Prerequisites

📋 Ensure you have the following:

  • ☕ Java Development Kit (JDK) 17+
  • 📦 Maven or Gradle installed
  • 🔤 A Java IDE (e.g., IntelliJ IDEA, Eclipse)

🛠️ Step 1: Add Dependencies

Include the following dependencies in your project:

Maven:

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

Gradle:

GROOVYbuild.gradle
implementation 'org.springframework.boot:spring-boot-starter-aop'

🛠️ Step 2: Define a Service

Create a simple service to demonstrate AOP.


🛠️ Step 3: Create an Aspect

Define an aspect to log method execution details.


🛠️ Step 4: Create a Controller

Expose the service methods through a REST controller.


▶️ Running the Application

Run the application using the following commands:

Spring Boot (Java/Kotlin): Run the application with either stack to confirm the baseline setup is working before deeper tests.

BASH
./mvnw spring-boot:run

Access the API at http://localhost:8080/api/users.


🧪 Testing the API

You can test the API using the following cURL commands:

  • Fetch all users:
BASH
curl -X GET http://localhost:8080/api/users
  • Fetch a user by ID:
BASH
curl -X GET http://localhost:8080/api/users/1

🏁 Conclusion

You now have a practical Aspect-Oriented Programming in Spring Boot implementation with a clear, production-friendly Spring Boot structure. As a next step, adapt configuration and tests to your own domain, then validate behavior under realistic traffic and failure scenarios.

Service

JAVAUserService.java
package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public String getUserById(String id) {
        return "User with ID: " + id;
    }

    public String getAllUsers() {
        return "Fetching all users.";
    }
}

Service

KOTLINUserService.kt
package com.example.demo.service

import org.springframework.stereotype.Service

@Service
class UserService {

    fun getUserById(id: String): String {
        return "User with ID: $id"
    }

    fun getAllUsers(): String {
        return "Fetching all users."
    }
}

Aspect

JAVALoggingAspect.java
package com.example.demo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Before("execution(* com.example.demo.service.UserService.*(..))")
    public void logBefore() {
        logger.info("Method execution started.");
    }
}

Aspect

KOTLINLoggingAspect.kt
package com.example.demo.aspect

import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component

@Aspect
@Component
class LoggingAspect {

    private val logger = LoggerFactory.getLogger(LoggingAspect::class.java)

    @Before("execution(* com.example.demo.service.UserService.*(..))")
    fun logBefore() {
        logger.info("Method execution started.")
    }
}

Controller

JAVAUserController.java
package com.example.demo.controller;

import com.example.demo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/{id}")
    public String getUserById(@PathVariable String id) {
        return userService.getUserById(id);
    }

    @GetMapping
    public String getAllUsers() {
        return userService.getAllUsers();
    }
}

Controller

KOTLINUserController.kt
package com.example.demo.controller

import com.example.demo.service.UserService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/users")
class UserController(
    private val userService: UserService
) {

    @GetMapping("/{id}")
    fun getUserById(@PathVariable id: String): String = userService.getUserById(id)

    @GetMapping
    fun getAllUsers(): String = userService.getAllUsers()
}