Aspect Oriented Programming

Aspect Oriented Programming #

Dalam pengembangan aplikasi skala menengah hingga besar, kita sering menemui logic yang berulang di banyak tempat: logging, security, transaction management, metrics, auditing, tracing, dan sebagainya. Logic ini bukan core business, tapi tetap wajib ada.

Jika diletakkan langsung di setiap method atau class, kode akan:

  • Sulit dibaca
  • Sulit dirawat
  • Mudah salah ketika ada perubahan

Di sinilah Aspect-Oriented Programming (AOP) menjadi relevan.

AOP membantu kita memisahkan cross-cutting concerns dari business logic utama, sehingga kode menjadi lebih bersih, modular, dan konsisten.

Apa Itu Aspect-Oriented Programming (AOP) #

Aspect-Oriented Programming adalah paradigma pemrograman yang berfokus pada pemisahan cross-cutting concerns ke dalam modul terpisah yang disebut aspect.


Cross-Cutting Concern Itu Apa? #

Cross-cutting concern adalah concern yang:

  • Muncul di banyak bagian aplikasi
  • Tidak spesifik ke satu domain bisnis

Contoh:

  • Logging
  • Authentication & Authorization
  • Transaction
  • Performance monitoring
  • Retry & circuit breaker

Tanpa AOP, concern ini akan tersebar di mana-mana.


Konsep Inti AOP #

Sebelum masuk ke implementasi Java, penting memahami istilah utama AOP:

Aspect #

Class yang berisi logic cross-cutting.

@Aspect
public class LoggingAspect {
}

Join Point #

Titik eksekusi dalam program, misalnya:

  • Eksekusi method
  • Akses field
  • Constructor call

Di Java AOP (Spring AOP), join point umumnya method execution.

Pointcut #

Ekspresi untuk memilih join point mana yang akan di-intercept.

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

Advice #

Kode yang dijalankan di sekitar join point.

Jenis advice:

  • @Before
  • @After
  • @AfterReturning
  • @AfterThrowing
  • @Around

Weaving #

Proses menggabungkan aspect dengan business logic.

Di Java:

  • Compile-time
  • Load-time
  • Runtime (Spring AOP menggunakan proxy)

Kenapa AOP Penting #

Kode Lebih Bersih #

Tanpa AOP:

public void transfer() {
    log.info("start transfer");
    validate();
    doTransfer();
    log.info("end transfer");
}

Dengan AOP:

public void transfer() {
    validate();
    doTransfer();
}

Single Responsibility Principle #

Business class hanya fokus pada domain logic, bukan concern tambahan.

Konsistensi Global #

  • Semua logging seragam
  • Semua transaction konsisten
  • Semua endpoint terlindungi

Implementasi AOP di Java (Spring AOP) #

Contoh berikut menggunakan Spring Boot + Spring AOP.

Logging Aspect #

Service Class #

@Service
public class OrderService {
    public void createOrder(String orderId) {
        System.out.println("Create order " + orderId);
    }
}

###** Logging Aspect

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("[LOG] Before method: " + joinPoint.getSignature());
    }

    @After("execution(* com.example.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("[LOG] After method: " + joinPoint.getSignature());
    }
}

Hasil #

Setiap method di service otomatis ter-log tanpa menyentuh kode aslinya.


Performance Monitoring (@Around) #

@Aspect
@Component
public class PerformanceAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object measureTime(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long end = System.currentTimeMillis();

        System.out.println("Method " + pjp.getSignature() + " took " + (end - start) + " ms");
        return result;
    }
}

Security / Authorization Aspect #

@Aspect
@Component
public class SecurityAspect {

    @Before("@annotation(RequireAdmin)")
    public void checkAdmin() {
        if (!SecurityContext.isAdmin()) {
            throw new RuntimeException("Forbidden");
        }
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireAdmin {}
@RequireAdmin
public void deleteUser(String userId) {}

Best Practice Menggunakan AOP #

Jangan Taruh Business Logic di Aspect #

❌ Salah:

  • Mengubah data domain
  • Mengambil keputusan bisnis

✅ Benar:

  • Logging
  • Validasi umum
  • Security
  • Metrics

Gunakan Pointcut yang Spesifik #

❌ Terlalu umum:

execution(* *(..))

✅ Lebih aman:

execution(* com.example.service..*(..))

Hindari Aspect Bertumpuk Berlebihan #

Terlalu banyak aspect:

  • Sulit di-debug
  • Flow sulit dipahami

Gunakan ordering jika perlu:

@Order(1)
@Aspect

Pahami Limitasi Spring AOP #

Spring AOP:

  • Berbasis proxy

  • Tidak bekerja untuk:

    • Method private
    • Internal method call (this.method())

Jika butuh interception lebih dalam → gunakan AspectJ.

Dokumentasikan Aspect #

Aspect itu “invisible”. Tanpa dokumentasi:

  • Engineer baru bingung
  • Bug sulit dilacak

Kapan TIDAK Menggunakan AOP #

  • Logic sangat sederhana
  • Aplikasi kecil
  • Overhead lebih besar dari manfaat

AOP itu powerful, tapi bukan silver bullet.


Kesimpulan #

Aspect-Oriented Programming membantu:

  • Memisahkan cross-cutting concern
  • Menjaga kebersihan kode
  • Meningkatkan maintainability

Di Java, terutama dengan Spring AOP:

  • Implementasi relatif mudah
  • Sangat cocok untuk logging, security, transaction, dan monitoring

Gunakan AOP dengan disiplin dan batasan yang jelas, maka manfaatnya akan terasa besar seiring bertambahnya skala sistem.

“Clean business logic, dirty work somewhere else — that’s where AOP shines.”

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact