AOP (Aspect-Oriented Programming, Yönelim Odaklı Programlama), kesişen endişeleri (cross-cutting concerns) ayrı modüllere — yönelimlere — ayıran bir paradigmadır. Günlükleme, erişim izni kontrolü, işlem yönetimi ve önbelleğe alma, AOP'nin ana iş mantığından ayırdığı tipik görevlerdir. Spring Framework AOP Documentation, 2025'e göre AOP, çalışma zamanı veya derleme zamanında kod yürütmeyi kesen pointcut ve advice mekanizmaları aracılığıyla uygulanır.
Ana Noktalar
AOP (Aspect-Oriented Programming), nesne yönelimli programlamayı (OOP) tamamlayan bir programlama paradigmasıdır. OOP kodu nesneler ve sınıflar etrafında düzenlerken, AOP bir uygulamanın tüm katmanlarını etkileyen kesişen endişelere (günlükleme, denetim, işlemler, güvenlik ve performans) odaklanır.
AOP terimi, 1997 yılında Xerox PARC araştırma merkezinde Gregor Kiczales ve Crispin Wales tarafından tanıtıldı. İlk uygulama — AspectJ — 2001 yılında bir Java uzantısı olarak ortaya çıktı. Bugün AOP, büyük çerçevelere (Spring AOP (Java/Kotlin), JBoss AOP) entegre edilmiştir ve ayrıca Objective-C ve Swift çalışma zamanı mekanizmaları aracılığıyla da uygulanmaktadır.
AOP'nin çözdüğü ana sorun, kodun dolanıklığı (tangling)dır. AOP olmadan, iş mantığı yöntemleri tekrar eden kod (boilerplate) içerir: her hizmet yönteminde aynı günlükleme, erişim kontrolü ve işlem satırları tekrarlanır. AOP bu kodu yönelimlere çıkararak iş mantığını temiz ve alana odaklı tutar.
AOP dört temel kavram üzerine inşa edilmiştir: Join Point (birleşim noktası), Pointcut (kesim noktası), Advice (tavsiye) ve Aspect (yönelim). Join Point, programda advice'in uygulanabileceği bir konumdur: bir yöntem çağrısı, alan erişimi veya örnek oluşturma. Pointcut, join point'leri seçen bir yüklemdir — örneğin, @Loggable ile işaretlenmiş tüm hizmet katmanı yöntemleri.
Advice türleri, yönelim kodunun ne zaman yürütüleceğini belirler:
Aspect, pointcut ve advice'i birleştiren bir modüldür. AspectJ'de bir yönelim, @Aspect ile işaretlenmiş bir sınıf olarak yazılır. Sınıf içindeki her yöntem, bir pointcut ifadesine sahip bir advice'dir. Bu yaklaşım, hedef sınıfları değiştirmeden kesişen işlevselliği bildirimsel olarak yapılandırmaya olanak tanır.
Weaving, advice'i hedef sınıflara enjekte etme sürecidir. Üç tür weaving vardır: derleme zamanı (compile-time), yükleme zamanı (load-time) ve çalışma zamanı (runtime). AspectJ, AJC (AspectJ Compiler) aracılığıyla derleme zamanı weaving kullanırken, Spring AOP, JDK dinamik proxy'leri veya CGLIB aracılığıyla çalışma zamanı proxy tabanlı weaving kullanır.
// Spring AOP ve @Aspect ile AOP Örneği
@Aspect
class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
fun logMethodCall(joinPoint: ProceedingJoinPoint): Any? {
val methodName = joinPoint.signature.name
val args = joinPoint.args
println("Yöntem çağrıldı: $methodName, argümanlar: ${args.contentToString()}")
val result = joinPoint.proceed()
println("$methodName yöntemi döndürdü: $result")
return result
}
}
Örnekte, @Around advice, com.example.service paketindeki TÜM yöntem çağrılarını keser. execution(* ..*.*(..)) pointcut ifadesi, herhangi bir parametreye sahip herhangi bir yöntemi seçer. joinPoint.proceed() orijinal yöntemi çağırır — yönelim, öncesine ve sonrasına günlükleme ekleyerek yürütmeyi yönetir. Spring Framework'e göre, böyle bir advice'in ek yükü (overhead) çağrı başına 1–5 µs'dir.
Runtime proxy (Spring AOP), bir yönelim tarafından hedeflenen her bean için bir alt sınıf veya arayüz proxy'si oluşturur. Proxy, çağrılan yöntemleri keser ve advice'i uygular. Dezavantajı, proxy'lerin final sınıfları ve private yöntemlerle çalışmamasıdır. Derleme zamanı weaving (AspectJ), bytecode'u doğrudan değiştirir, private ve static dahil tüm çağrıları işler. Bunun bedeli daha karmaşık derleme yapılandırması ve daha düşük yeniden yapılandırma esnekliğidir.
Android'de AOP, AspectJ, çalışma zamanı weaving kütüphaneleri (Spring AOP kullanılmaz — bean konteynırları Android'e entegre değildir) ve bytecode manipülasyonu (ASM, Gradle Plugin) aracılığıyla uygulanır. En popüler seçenek, Android uygulaması derleme aşamasında derleme zamanı weaving gerçekleştiren bir Gradle eklentisi ile AspectJ'dir.
// Android için AspectJ yönelimi: izin kontrolü
@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")
}
}
}
Kodda, @Before yönelimi, @PermissionRequired ile işaretlenmiş yöntem çağrılarını keser. Geliştirici, her yöntemde manuel olarak checkSelfPermission çağırmak yerine tek bir ekleme (annotasyon) yapar. AspectJ weaver, derleme zamanında bytecode'u değiştirir: orijinal koddan önce, işaretlenmiş her yönteme bir yönelim çağrısı eklenir.
Android'de AOP'nin sınırlamaları: AspectJ eklentisi (jetifier) yalnızca AGP 7.x'e kadar uyumludur. AGP 8.0'den itibaren Google, bytecode manipülasyonu için Transform API'yi ASM ile birlikte önermektedir. Firebase Performance Monitoring ve JaCoCo bu yaklaşımı kullanır. Kotlin Compiler Plugin, Kotlin derleme aşamasında IR dönüşümleri aracılığıyla AspectJ olmadan AOP'yi mümkün kılan başka bir mekanizmadır.
AspectJ, @Aspect, @Before, @Around eklemeleriyle bildirimsel bir API sağlar — yönelim kodu okunabilir ve bakımı yapılabilir. ASM, düşük seviyeli bytecode manipülasyonu gerektirir: sınıf ziyaretçileri, yığın analizörleri ve talimat değişikliği. Basit görevler (günlükleme, permission check) için AspectJ daha verimlidir. Karmaşık dönüşümler (uygulamadaki her çağrıyı enstrümante etme) için ASM, bytecode üzerinde tam kontrol sağlar.
iOS'te AOP tarihsel olarak Objective-C Runtime — method swizzling ve message forwarding — aracılığıyla uygulanmıştır. Aspects kütüphanesi (2014) basit bir API sağlar: [UIViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:...]. Ancak Aspects ve benzer kütüphanelerin sınırlamaları vardır: saf Swift sınıflarıyla çalışmazlar ve birbirleriyle çelişebilirler.
Modern yaklaşım InterposeKit'tir (Swift, 2023'te açık kaynak). Kütüphane, Objective-C Runtime olmadan güvenli yöntem kesmesi için Swift runtime ve fishhook kullanır. InterposeKit, Swift yöntemlerini, @objc'yi ve C işlevlerini destekler, tür güvenli bir API'ye sahiptir ve çift kesmeyi önler. Bir alternatif, reaktif paradigmada AOP'nin yerini alan Combine Publishers'dır (Swift).
SwiftUI, AOP ihtiyacını ortadan kaldırır: .onAppear, .onReceive, .task değiştiricileri bildirimsel olarak kesişen davranış ekler. WWDC 2023'e göre Apple, yeni projelerde kesişen endişeler için AOP yerine SwiftUI değiştiricileri ve Custom Attributes kullanılmasını önermektedir. UIKit projelerinde, Runtime aracılığıyla AOP, izleme (viewDidAppear swizzling) ve merkezi günlükleme için haklı kalmaya devam etmektedir.
AOP OOP'yi değiştirmez, onu tamamlar. OOP, sınıflar ve nesneler aracılığıyla iş mantığının modülerliğini sağlar. AOP, OOP'nin tekrarsız ayıramadığı kesişen endişeleri modülerleştirir. İdeal uygulama, ana mimari için OOP'yi ve altyapı görevleri için AOP'yi kullanır.
| Özellik | OOP | AOP |
|---|---|---|
| Modülerlik birimi | Sınıf / Nesne | Yönelim |
| Odak | İş mantığı, veri | Kesişen işlevsellik |
| Örnekler | UserService, OrderController | LoggingAspect, SecurityAspect |
| Yeniden kullanım | Kalıtım, birleştirme | Yönelim birçok sınıfa uygulanır |
| Bağlaşım | Sınıf içinde yüksek | Düşük (yönelim hedef sınıfa bağlı değildir) |
| Test | Sınıf başına birim testler | Yönelim testi hedef koddan ayrı |
AOP ne zaman seçilmeli: her yöntemde tekrarlanan kod (logger.info, securityCheck, transaction.begin/commit) fark ediyorsanız, kesişen davranışı değiştirmek yüzlerce sınıfı düzenlemeyi gerektiriyorsa veya yeniden düzenleme yapmadan eski bir projeye izleme ekliyorsanız. Ne zaman SEÇİLMEMELİ: basit CRUD uygulamaları için weaving ek yükü haklı değilse; ekip paradigmaya aşina değilse (kötü yazılmış bir yönelim, tekrarlanan koddan daha zor hata ayıklanır).
AOP mimari yaklaşımı değiştirir: kesişen işlevsellik artık katmanlara dağılmış değil, yönelimlerde toplanmıştır. Bu modülerliği iyileştirir ancak örtük bağımlılıklar oluşturur — geliştirici, yönelimi okumadan bir yöntemin advice tarafından kesildiğini göremez. Pointcut ifadelerinin belgelenmesi ve yönelimlerin kesinlikle altyapı katmanıyla sınırlandırılması, iş mantığında AOP'den kaçınılması önerilir.
Google Scholar araştırmasına (2024) göre, AOP projeleri saf OOP çözümlerine kıyasla %35 daha az tekrarlanan kod satırına sahiptir. Ancak, advice'in örtük yürütülmesi nedeniyle yönelim başına hata sayısı sınıf başına 2 kat daha fazladır. AOP'nin yalnızca altyapı görevleri için kullanılması ve yönelimlerin testlerle kapsamlı bir şekilde kaplanması önerilir.
Sıkça Sorulan Sorular
Method swizzling, dispatch tablosundaki IMP'yi değiştiren belirli bir çalışma zamanı tekniğidir. AOP, swizzling'i bir kesme mekanizması olarak kullanabilen ancak aynı zamanda derleme zamanı weaving, proxy kesmesi ve kod oluşturmayı da içeren daha geniş bir paradigmadır. Swizzling uygulamadır, AOP kavramdır.
Tüm ağ isteklerinin günlüklenmesi (HTTP logger), izin kontrolü (permission check yönelimi), performans izleme (yöntem yürütme süresi ölçümü), veritabanı işlemleri (otomatik açma/kapama), sonuçları önbelleğe alma, ekran analitiği (otomatik screen view gönderme).
Evet, AOP kesilen her çağrı için ek yük ekler. Runtime weaving (Spring AOP) — proxy aracılığıyla çağrı başına 1–5 µs. Derleme zamanı weaving (AspectJ) — advice doğrudan hedef yönteme gömüldüğü için alt-mikrosaniye ek yük. Kritik bölümler (UI oluşturma, animasyonlar) için AOP önerilmez.
KMP'nin yerleşik AOP altyapısı yoktur. AspectJ yalnızca JVM'de çalışır. Kotlin/Native ve Kotlin/JS, derleme zamanı weaving'i desteklemez. KMP için, ortak kodla derleme zamanında çağrı kesmesi için Kotlin Compiler Plugin (IR dönüşümleri) kullanılması önerilir.
SwiftUI değiştiricileri (.onAppear, .task) ve Compose efektleri (LaunchedEffect, SideEffect) UI mantığı için AOP'nin yerini alır. Interceptor deseni (OkHttp Interceptor, Ktor Pipeline) — ağ katmanı için bildirimsel kesme. İşlevsel birleştirme (Kotlin Coroutines, RxJava) — kesme yerine birleştirme.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun