AOP in Mobile Applications — Essence, Principles and How to Apply in Development

Author: IT Sectr Published: 2026-05-17 Reading time: 9 min

AOP (Aspect-Oriented Programming) is a paradigm that separates cross-cutting concerns into dedicated modules — aspects. Logging, permission checks, transaction handling, and caching are typical tasks that AOP isolates from the main business logic. According to Spring Framework AOP Documentation, 2025, AOP is implemented through pointcut and advice mechanisms that intercept code execution at runtime or compile time.

Key Takeaways

  • AOP is a paradigm that separates cross-cutting concerns from business logic through aspects.
  • Advice is code that executes before, after, or around the target method (before, after, around).
  • Pointcut is an expression that determines which methods the advice applies to.
  • AspectJ is the main AOP implementation for Java/Android with compile-time weaving and LTW.
  • Objective-C AOP is implemented via method swizzling and the Aspects / InterposeKit libraries.

What Is AOP (Aspect-Oriented Programming)?

AOP (Aspect-Oriented Programming) is a programming paradigm that complements object-oriented programming (OOP). While OOP organizes code around objects and classes, AOP focuses on cross-cutting concerns that permeate all layers of an application: logging, auditing, transactions, security, and performance.

The term AOP was introduced by Gregor Kiczales and Crispin Wales at the Xerox PARC research center in 1997. The first implementation — AspectJ — appeared in 2001 as a Java extension. Today AOP is built into major frameworks: Spring AOP (Java/Kotlin), JBoss AOP, and is also implemented via Objective-C and Swift runtime mechanisms.

The main problem that AOP solves is tangling of code. Without AOP, business logic methods contain boilerplate: the same logging, access checks, and transaction code are repeated in every service method. AOP extracts this code into aspects, keeping business logic clean and focused on the domain.

Core AOP Components: Advice, Pointcut and Join Point

AOP is built on four key concepts: Join Point, Pointcut, Advice, and Aspect. A Join Point is a location in the program where advice can be applied: a method call, field access, or instance creation. A Pointcut is a predicate that selects join points — for example, all service-layer methods annotated with @Loggable.

The types of advice determine when the aspect code executes:

  • Before — executes before the target method call. Used for access validation and auditing.
  • After — executes after the call (always, on success, or on exception). Used for resource release and completion logging.
  • Around — fully controls the call: it can execute code before, after, or completely replace the target method. The most powerful and dangerous type of advice.
  • AfterReturning — executes only on successful method completion. Used for caching the result.
  • AfterThrowing — executes when an exception is thrown. Used for centralized error handling.

Aspect is a module that combines a pointcut and advice. In AspectJ, an aspect is written as a class annotated with @Aspect. Each method inside the class is an advice with a pointcut expression. This approach allows configuring cross-cutting functionality declaratively without modifying target classes.

How AOP Works: Weaving and Call Interception

Weaving is the process of injecting advice into target classes. There are three types of weaving: compile-time, load-time, and runtime. AspectJ uses compile-time weaving via the AJC (AspectJ Compiler), while Spring AOP uses runtime proxy-based weaving through JDK dynamic proxies or CGLIB.

kotlin
// AOP example with Spring AOP and @Aspect
@Aspect
class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    fun logMethodCall(joinPoint: ProceedingJoinPoint): Any? {
        val methodName = joinPoint.signature.name
        val args = joinPoint.args
        println("Method called: $methodName, arguments: ${args.contentToString()}")

        val result = joinPoint.proceed()

        println("Method $methodName returned: $result")
        return result
    }
}

In the example, the @Around advice intercepts ALL method calls in the com.example.service package. The pointcut expression execution(* ..*.*(..)) selects any method with any parameters. joinPoint.proceed() calls the original method — the aspect manages execution by adding logging before and after. According to Spring Framework, the overhead of such advice is 1–5 µs per call.

Runtime vs compile-time weaving

Runtime proxy (Spring AOP) creates a subclass or interface proxy for each bean targeted by an aspect. The proxy intercepts the called methods and applies the advice. The drawback is that proxies don't work with final classes or private methods. Compile-time weaving (AspectJ) modifies the bytecode directly, handling all calls including private and static ones. The trade-off is more complex build configuration and less reconfiguration flexibility.

AOP in Android: AspectJ and Libraries

AOP on Android is implemented via AspectJ, runtime weaving libraries (Spring AOP is not used since bean containers are not built into Android), and bytecode manipulation (ASM, Gradle Plugin). The most popular option is AspectJ with a Gradle plugin that performs compile-time weaving during the Android app build phase.

kotlin
// AspectJ aspect for Android: permission check
@Aspect
class PermissionAspect {

    @Before("execution(@PermissionRequired * *(..))")
    fun checkPermission(joinPoint: JoinPoint) {
        val annotation = joinPoint.signature
            .declaringType.
            getDeclaredMethod(joinPoint.signature.name)
            .getAnnotation(PermissionRequired::class.java)

        val permission = annotation.value
        if (!ContextCompat.checkSelfPermission(
                context, permission)) {
            throw SecurityException("Permission $permission denied")
        }
    }
}

In the code, the @Before aspect intercepts method calls annotated with @PermissionRequired. Instead of manually calling checkSelfPermission in every method, the developer adds a single annotation. The AspectJ weaver modifies the bytecode at compile time: an aspect call is inserted into each annotated method before the original code.

Limitations of AOP on Android: the AspectJ plugin (jetifier) is only compatible with AGP up to 7.x. Starting with AGP 8.0, Google recommends Transform API with ASM for bytecode manipulation. Firebase Performance Monitoring and JaCoCo use this approach. The Kotlin Compiler Plugin is another mechanism that enables AOP without AspectJ through IR transformations at the Kotlin compilation stage.

AspectJ vs ASM: Which to Choose for Android

AspectJ provides a declarative API with @Aspect, @Before, @Around annotations — the aspect code is readable and maintainable. ASM requires low-level bytecode manipulation: class visitors, stack analyzers, and instruction modification. For simple tasks (logging, permission checks), AspectJ is more efficient. For complex transformations (instrumenting every call in the application), ASM gives full control over the bytecode.

AOP in iOS: Objective-C Runtime and Swift Approaches

AOP on iOS has historically been implemented through the Objective-C Runtime — method swizzling and message forwarding. The Aspects library (2014) provides a simple API: [UIViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:...]. However, Aspects and similar libraries have limitations: they don't work with pure Swift classes and can conflict with each other.

The modern approach is InterposeKit (Swift, open-sourced in 2023). The library uses Swift runtime and fishhook for safe method interception without Objective-C Runtime. InterposeKit supports Swift methods, @objc, and C functions, has a type-safe API, and prevents double interception. An alternative is Combine Publishers (Swift), which replace AOP in the reactive paradigm.

SwiftUI eliminates the need for AOP: .onAppear, .onReceive, .task modifiers add cross-cutting behavior declaratively. According to WWDC 2023, Apple recommends using SwiftUI modifiers and Custom Attributes instead of AOP for cross-cutting concerns in new projects. In UIKit projects, AOP through Runtime remains justified for monitoring (swizzling viewDidAppear) and centralized logging.

AOP vs OOP: Comparison and When to Choose

AOP does not replace OOP, but complements it. OOP provides modularity of business logic through classes and objects. AOP modularizes cross-cutting concerns that OOP cannot isolate without duplication. The ideal application uses OOP for the main architecture and AOP for infrastructure tasks.

CharacteristicOOPAOP
Unit of modularityClass / ObjectAspect
FocusBusiness logic, dataCross-cutting concerns
ExamplesUserService, OrderControllerLoggingAspect, SecurityAspect
ReuseInheritance, compositionAspect applied to many classes
CouplingHigh within a classLow (aspect does not depend on target class)
TestingUnit tests per classAspect testing separate from target code

When to choose AOP: if you notice repeated boilerplate in every method (logger.info, securityCheck, transaction.begin/commit), if changing cross-cutting behavior requires editing hundreds of classes, or if you're introducing monitoring into a legacy project without refactoring. When NOT to choose: for simple CRUD applications where weaving overhead isn't justified; if the team is not familiar with the paradigm (a poorly written aspect is harder to debug than duplicated code).

AOP Impact on Project Architecture

AOP changes the architectural approach: cross-cutting functionality is no longer scattered across layers but gathered in aspects. This improves modularity but creates implicit dependencies — a developer cannot see that a method is intercepted by advice without reading the aspect. It is recommended to document pointcut expressions and strictly limit aspects to the infrastructure layer, avoiding AOP in business logic.

According to a Google Scholar study (2024), AOP projects have 35% fewer lines of duplicated code compared to purely OOP solutions. However, the number of bugs per aspect is 2 times higher than per class due to the implicit execution of advice. It is recommended to use AOP only for infrastructure tasks and thoroughly cover aspects with tests.

Frequently Asked Questions

How is AOP different from method swizzling?

Method swizzling is a specific runtime technique for replacing IMP in the dispatch table. AOP is a broader paradigm that can use swizzling as an interception mechanism but also includes compile-time weaving, proxy interception, and code generation. Swizzling — implementation, AOP — concept.

What tasks does AOP solve in mobile development?

Logging all network requests (HTTP logger), permission checking (permission check aspect), performance monitoring (method execution time measurement), database transactions (automatic open/close), result caching, screen analytics (automatic screen view sending).

Does AOP affect application performance?

Yes, AOP adds overhead for each intercepted call. Runtime weaving (Spring AOP) — 1–5 µs per call via proxy. Compile-time weaving (AspectJ) — sub-microsecond overhead since advice is embedded directly into the target method. AOP is not recommended for critical sections (UI rendering, animations).

Does AOP work with Kotlin Multiplatform?

KMP does not have built-in AOP infrastructure. AspectJ only works on JVM. Kotlin/Native and Kotlin/JS do not support compile-time weaving. For KMP, it is recommended to use the Kotlin Compiler Plugin (IR transformations) for call interception at compile time with shared code.

What alternatives to AOP exist in modern architectures?

SwiftUI modifiers (.onAppear, .task) and Compose effects (LaunchedEffect, SideEffect) replace AOP for UI logic. Interceptor pattern (OkHttp Interceptor, Ktor Pipeline) — declarative interception for the networking layer. Functional composition (Kotlin Coroutines, RxJava) — composition instead of interception.

Summary

  • AOP is a paradigm that isolates cross-cutting concerns into aspects with advice and pointcut.
  • Advice types — Before, After, Around, AfterReturning, AfterThrowing — determine when the aspect executes.
  • Weaving — compile-time (AspectJ), load-time (LTW), and runtime (Spring AOP proxy).
  • On Android AOP is implemented via AspectJ, ASM bytecode manipulation, and the Kotlin Compiler Plugin.
  • On iOS AOP uses the Objective-C Runtime (swizzling), InterposeKit, or SwiftUI modifiers.
  • AOP does not replace OOP — it complements it for infrastructure tasks without code duplication.
  • It is recommended to use AOP for monitoring, security, and transactions, avoiding it in performance-critical sections.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also