← Kursa Dön
📄 Text · 25 min

AOP Nedir?

Yazılım geliştirmede bazı endişeler (concern) uygulamanın birçok katmanına yayılır: loglama, güvenlik kontrolü, transaction yönetimi, performans ölçümü, cache, hata yönetimi gibi. Bu tür endişelere cross-cutting concern (kesişen endişe) denir çünkü tek bir modüle veya sınıfa sınırlı kalmazlar — uygulamanın tamamını yatay olarak keserler.

Cross-Cutting Concern Problemi

OOP (Object-Oriented Programming) ile iş mantığını güzel bir şekilde sınıflara bölebilirsiniz. Ancak loglama gibi bir endişeyi düşünün:

// AOP olmadan — loglama kodu HER YERE yayılır
@Service
public class OrderService {
    public Order createOrder(OrderRequest request) {
        log.info("createOrder başladı: {}", request);          // ← loglama
        long start = System.currentTimeMillis();                // ← performans
        securityService.checkPermission("ORDER_CREATE");        // ← güvenlik

        Order order = processOrder(request);

        long elapsed = System.currentTimeMillis() - start;     // ← performans
        log.info("createOrder tamamlandı: {}ms", elapsed);     // ← loglama
        return order;
    }
}

@Service
public class PaymentService {
    public PaymentResult processPayment(PaymentRequest request) {
        log.info("processPayment başladı: {}", request);       // ← AYNI loglama
        long start = System.currentTimeMillis();               // ← AYNI performans
        securityService.checkPermission("PAYMENT_PROCESS");    // ← AYNI güvenlik

        PaymentResult result = doPayment(request);

        long elapsed = System.currentTimeMillis() - start;    // ← AYNI performans
        log.info("processPayment tamamlandı: {}ms", elapsed); // ← AYNI loglama
        return result;
    }
}

Aynı loglama, performans ve güvenlik kodu her serviste tekrarlanır. Bu durum birçok probleme yol açar:

  • Code Duplication: Aynı kod onlarca sınıfta tekrarlanır

  • Tangled Code (Karmaşık Kod): İş mantığı, loglama ve güvenlik kodu iç içe geçer

  • Bakım Zorluğu: Loglama formatını değiştirmek istediğinizde tüm sınıfları güncellemeniz gerekir

  • Single Responsibility İhlali: Servis sınıfı hem iş mantığından hem loglamadan sorumlu

AOP'nin Çözümü

AOP, cross-cutting concern'leri iş mantığından ayırarak ayrı modüllere (aspect) taşımanızı sağlar. İş mantığı sınıfları sadece kendi sorumluluğuna odaklanır; loglama, güvenlik gibi endişeler aspect olarak tanımlanır ve Spring tarafından otomatik olarak uygulanır.

// AOP ile — servis sınıfı SADECE iş mantığı içerir
@Service
public class OrderService {
    public Order createOrder(OrderRequest request) {
        return processOrder(request);  // Temiz, saf iş mantığı!
    }
}

// Loglama endişesi ayrı bir aspect'te
@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("{} başladı", joinPoint.getSignature().getName());
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        log.info("{} tamamlandı: {}ms",
            joinPoint.getSignature().getName(),
            System.currentTimeMillis() - start);
        return result;
    }
}

Artık loglama kodu tek bir yerde tanımlanır ve tüm servis metotlarına otomatik uygulanır. Servis sınıfları tertemizdir.

AOP Terminolojisi

AOP'nin kendine özgü bir terminolojisi vardır. Bu terimleri anlamak, Spring AOP'yi etkili kullanmanın temelidir:

Aspect (Kesit): Cross-cutting concern'in modülerleştirilmiş hali. Bir aspect, ne zaman (pointcut) ve ne yapılacağını (advice) tanımlar. Örnek: LoggingAspect, SecurityAspect, TransactionAspect.

Join Point (Birleşim Noktası): Aspect'in uygulanabileceği program noktası. Spring AOP'de join point her zaman bir metot çağrısıdır. (AspectJ'de constructor, field erişimi vb. de olabilir, ama Spring AOP sadece metot execution'ını destekler.)

Advice (Tavsiye/Eylem): Aspect'in join point'te gerçekleştirdiği eylem. Beş türü vardır:

  • @Before — metot çalışmadan önce

  • @After — metot çalıştıktan sonra (başarılı veya başarısız)

  • @AfterReturning — metot başarıyla döndükten sonra

  • @AfterThrowing — metot exception fırlattıktan sonra

  • @Around — metot çağrısını tamamen sarar (en güçlü)

Pointcut (Kesim Noktası): Advice'ın hangi join point'lerde çalışacağını belirleyen ifade. Bir pattern matching mekanizmasıdır: "com.example.service paketindeki tüm metotlar" gibi.

Weaving (Dokuma): Aspect'lerin hedef nesnelere uygulanma sürecidir. Spring AOP'de weaving çalışma zamanında (runtime) proxy nesneler oluşturarak gerçekleşir.

Target Object (Hedef Nesne): Aspect'in uygulandığı asıl nesne. Proxy'nin arkasındaki gerçek bean.

Terminoloji Görselleştirmesi:

@Aspect LoggingAspect {           ← Aspect
    @Around(                      ← Advice türü
        "execution(* service.*.*(..))"  ← Pointcut ifadesi
    )
    public Object log(ProceedingJoinPoint jp) {  ← jp = Join Point
        // before logic
        Object result = jp.proceed();  ← Target method çağrısı
        // after logic
        return result;
    }
}

Weaving (çalışma zamanı):
Client → Proxy → [LoggingAspect] → Target.method()

Spring AOP vs AspectJ

Spring AOP ve AspectJ, iki farklı AOP implementasyonudur:

ÖzellikSpring AOPAspectJ
Weaving zamanıRuntime (proxy)Compile-time veya load-time
Join pointSadece metot executionMetot, constructor, field, vb.
PerformansProxy overhead'i varDaha hızlı (compile-time weaving)
KarmaşıklıkBasit, Spring ile entegreDaha güçlü ama daha karmaşık
Self-invocationÇalışmaz (proxy bypass)Çalışır
Kullanım%95 senaryo için yeterliÇok spesifik ihtiyaçlar için

Spring AOP, çoğu kurumsal uygulama için fazlasıyla yeterlidir. AspectJ'e ihtiyaç duyacağınız senaryolar çok nadirdir (constructor interception, private metot interception gibi).

AOP Kullanım Alanları

AlanAçıklamaSpring Örneği
LoglamaMetot giriş/çıkış, parametre, süreCustom @LogExecution
GüvenlikYetki kontrolü@PreAuthorize, @Secured
TransactionVeritabanı transaction yönetimi@Transactional
CacheSonuç önbellekleme@Cacheable
RetryBaşarısız işlemi tekrar deneme@Retryable
Rate Limitingİstek hızı sınırlamaCustom @RateLimit
ValidationParametre doğrulama@Valid
MonitoringPerformans metrikleriMicrometer + @Timed

Spring'in birçok özelliği (@Transactional, @Cacheable, @Secured) aslında AOP ile implement edilmiştir. Bu anotasyonları kullandığınızda arka planda AOP çalışır.