CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-boot--spring-boot-starter-aop

Spring Boot starter for aspect-oriented programming with Spring AOP and AspectJ

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Spring Boot Starter AOP

Spring Boot starter for aspect-oriented programming with Spring AOP and AspectJ. This starter automatically configures Spring AOP support and enables developers to implement cross-cutting concerns like logging, security, transactions, and caching through declarative programming using annotations and pointcut expressions.

Package Information

  • Package Name: spring-boot-starter-aop

  • Group ID: org.springframework.boot

  • Language: Java

  • Installation:

    implementation 'org.springframework.boot:spring-boot-starter-aop:3.5.3'

    For Maven:

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

Core Imports

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
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.Pointcut;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;

Basic Usage

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Executing: " + joinPoint.getSignature().getName());
    }
    
    @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("Completed: " + joinPoint.getSignature().getName() + 
                          " with result: " + result);
    }
}

Configuration Properties

The starter provides these configuration properties for customizing AOP behavior:

# Enable/disable AOP auto-configuration
# Type: Boolean
# Default: true (when missing, defaults to true)
# Description: Add @EnableAspectJAutoProxy support
spring.aop.auto=true

# Control proxy type for AOP proxies
# Type: Boolean  
# Default: true (when missing, defaults to true)
# Description: Whether subclass-based (CGLIB) proxies are to be created (true), 
#              as opposed to standard Java interface-based proxies (false)
spring.aop.proxy-target-class=true

Architecture

The starter enables AOP through several key components:

  • Auto-Configuration: AopAutoConfiguration automatically enables @EnableAspectJAutoProxy when conditions are met
  • Proxy Creation: Automatic proxy creation for beans matching defined pointcuts
  • Weaving Support: Runtime weaving through AspectJ weaver dependency
  • Conditional Configuration: Different proxy strategies based on AspectJ availability and configuration

Capabilities

Aspect Definition

Create aspects by combining @Aspect with @Component annotations.

@Aspect
@Component
public class AspectName {
    // Aspect methods with advice annotations
}

Pointcut Expressions

Define join points where advice should be executed.

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayerPointcut() {}

@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")  
public void transactionalMethods() {}

@Pointcut("within(com.example.controller..*)")
public void controllerPackage() {}

Common Pointcut Expressions:

  • execution(* package.Class.method(..)) - Method execution
  • within(package..*) - Within package or subpackages
  • @annotation(AnnotationType) - Methods with specific annotation
  • args(ArgType) - Methods with specific argument types
  • target(TargetType) - Methods on specific target types

Before Advice

Execute advice before method execution.

/**
 * Executes before the target method
 * @param joinPoint - Provides access to method signature and arguments
 */
@Before("pointcut-expression")
public void beforeAdvice(JoinPoint joinPoint) {
    // Advice logic
}

After Returning Advice

Execute advice after successful method completion.

/**
 * Executes after method returns successfully
 * @param joinPoint - Provides access to method signature and arguments
 * @param result - The return value (optional parameter)
 */
@AfterReturning(pointcut = "pointcut-expression", returning = "result")
public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
    // Advice logic
}

After Throwing Advice

Execute advice after method throws an exception.

/**
 * Executes after method throws an exception
 * @param joinPoint - Provides access to method signature and arguments  
 * @param exception - The thrown exception (optional parameter)
 */
@AfterThrowing(pointcut = "pointcut-expression", throwing = "exception")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception exception) {
    // Exception handling logic
}

After (Finally) Advice

Execute advice after method completion (success or exception).

/**
 * Executes after method completion regardless of outcome
 * @param joinPoint - Provides access to method signature and arguments
 */
@After("pointcut-expression")
public void afterAdvice(JoinPoint joinPoint) {
    // Cleanup logic
}

Around Advice

Execute advice around method execution with control over method invocation.

/**
 * Executes around method execution with full control
 * @param proceedingJoinPoint - Allows proceeding with method execution
 * @return Object - Must return the method result or alternative value
 * @throws Throwable - Can throw exceptions
 */
@Around("pointcut-expression")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    // Before logic
    Object result = proceedingJoinPoint.proceed(); // Execute target method
    // After logic  
    return result;
}

Types

JoinPoint Interface

Provides access to join point information in advice methods.

interface JoinPoint {
    /** Get method signature information */
    Signature getSignature();
    
    /** Get method arguments */
    Object[] getArgs();
    
    /** Get target object instance */
    Object getTarget();
    
    /** Get proxy object instance */
    Object getThis();
    
    /** Get join point kind (METHOD_EXECUTION, etc.) */
    String getKind();
    
    /** Get source location information */
    SourceLocation getSourceLocation();
}

ProceedingJoinPoint Interface

Extended join point interface for around advice with execution control.

interface ProceedingJoinPoint extends JoinPoint {
    /** Proceed with original method execution */
    Object proceed() throws Throwable;
    
    /** Proceed with modified arguments */
    Object proceed(Object[] args) throws Throwable;
}

Signature Interface

Provides method signature information.

interface Signature {
    /** Get method name */
    String getName();
    
    /** Get declaring type */
    Class<?> getDeclaringType();
    
    /** Get method modifiers */
    int getModifiers();
    
    /** Get string representation */
    String toString();
}

Auto-Configuration Details

AopAutoConfiguration

/**
 * Auto-configuration for Spring AOP support
 * Equivalent to enabling @EnableAspectJAutoProxy
 * Conditionally activated based on spring.aop.auto property
 */
@AutoConfiguration
@ConditionalOnBooleanProperty(name = "spring.aop.auto", matchIfMissing = true)
public class AopAutoConfiguration {
    // Configuration classes for different proxy strategies
}

Configuration Classes:

  • AspectJAutoProxyingConfiguration: Enabled when org.aspectj.weaver.Advice is on classpath
  • JdkDynamicAutoProxyConfiguration: JDK dynamic proxies (interface-based) when spring.aop.proxy-target-class=false
  • CglibAutoProxyConfiguration: CGLIB proxies (subclass-based) when spring.aop.proxy-target-class=true (default)
  • ClassProxyingConfiguration: Fallback proxy configuration when AspectJ weaver not available

Usage Examples

Service Layer Monitoring

@Aspect
@Component
public class ServiceMonitor {
    
    private static final Logger logger = LoggerFactory.getLogger(ServiceMonitor.class);
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object monitorServiceCall(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        long startTime = System.currentTimeMillis();
        
        try {
            logger.info("Starting method: {}", methodName);
            Object result = joinPoint.proceed();
            long duration = System.currentTimeMillis() - startTime;
            logger.info("Completed method: {} in {}ms", methodName, duration);
            return result;
        } catch (Exception e) {
            logger.error("Method {} failed: {}", methodName, e.getMessage());
            throw e;
        }
    }
}

Security Aspect

@Aspect
@Component
public class SecurityAspect {
    
    @Before("@annotation(secured)")
    public void checkSecurity(JoinPoint joinPoint, Secured secured) {
        // Get current user context
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        
        if (auth == null || !auth.isAuthenticated()) {
            throw new SecurityException("User not authenticated");
        }
        
        // Check required roles
        String[] requiredRoles = secured.value();
        boolean hasRole = Arrays.stream(requiredRoles)
            .anyMatch(role -> auth.getAuthorities().stream()
                .anyMatch(authority -> authority.getAuthority().equals(role)));
                
        if (!hasRole) {
            throw new SecurityException("Insufficient permissions");
        }
    }
}

Transaction Management

@Aspect
@Component
public class TransactionAspect {
    
    @AfterThrowing(pointcut = "@annotation(transactional)", throwing = "exception")
    public void handleTransactionException(JoinPoint joinPoint, 
                                         Transactional transactional, 
                                         Exception exception) {
        // Custom transaction rollback logic
        String methodName = joinPoint.getSignature().getName();
        logger.error("Transaction rolled back for method: {} due to: {}", 
                    methodName, exception.getMessage());
    }
}

Notes

  • This starter automatically enables AOP when added to classpath
  • No manual @EnableAspectJAutoProxy annotation required
  • Supports both Spring AOP (proxy-based) and AspectJ (weaving-based) approaches
  • Uses CGLIB proxies by default for maximum compatibility
  • Aspects must be Spring beans (use @Component or equivalent)
  • Pointcut expressions follow AspectJ syntax
  • Performance impact: proxying adds minimal overhead for intercepted methods

docs

index.md

tile.json