Aspect Oriented Programming (AOP) Nedir? Neden Önemlidir?
--
Aspect oriented programming kısa adıyla AOP, uygulamanızdaki iş mantığı (business logic) ile uygulamanızın genelinde ortak kullanılabilecek olan yapıların ayrılmasını sağlar. İş mantığı haricindeki yapılara örnek verecek olursak; logging, exception handling, caching, authentication, authorization, transaction vb. işlemlerdir.
Bir Spring Boot örneğiyle teorik bilgimizi pekiştirelim.
Bu örnekte projemizin yapısı önemli olacağı için bir ekran görüntüsüyle başlayalım.
Öncelikle AOP’yi projemizde kullanabilmek için gerekli bağımlılıkları pom.xml dosyasına eklemeliyiz.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.14</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
Bu bağımlılıklara ek olarak uygulamamız web uygulaması olacağından dolayı web bağımlılığını da ekliyoruz.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Oluşturulmuş olan aspect sınıflarının devreye girmesi için main sınıfımıza @EnableAspectJAutoProxy anotasyonunu ekliyoruz.
CourseController adında bir sınıf oluşturuyoruz.
Buradaki endpoint’lere istek gönderildiğinde ilgili aspect metodu devreye girecektir.
Loglama işlemlerini yapacak olan LoggingAspect sınıfını oluşturuyoruz.
Bu sınıfın aspect bir sınıf olduğunu 7. satırdaki @Aspect anotasyonuyla belirliyoruz ve bunu bir component olarak tanımlıyoruz.
11. satırdaki @Before anotasyonu, hangi metotlar çağrılmadan önce çalışacağını belirtir. Bu örneği detaylıca inceleyelim.
- execution anahtar kelimesinden hemen sonra gelen yıldız (*) simgesi herhangi bir dönüş tipi (return type) olabileceği anlamına gelir.
- Yıldızdan sonraki ilk kısım paket adı (com.metin.medium.aop.controller) daha sonra sınıf adı (CourseController) ve son olarak metot adı (registerCourse) olacaktır.
- Parantez içerisindeki iki nokta (..) simgesi, herhangi bir parametre olabileceği anlamına gelir.
12. satırdaki JoinPoint parametresi, aspect sınıfını tetikleyen metodun bilgisini verir.
http://localhost:8080/courses/registering/34/66 adresine istek gönderdikten sonra;
- 13. satır, 34 değerini verecektir. Metoda gelen ilk parametrenin değeridir.
- 14. satır, yakalanan metodun hangi sınıfta olduğu bilgisini verir. com.metin.medium.aop.controller.CourseController@2c0fa3e3
- 15. satır, yakalanan metodun imzasıdır. void com.metin.medium.aop.controller.CourseController.registerCourse(Long,Long)
- İlgili metotlar çalışmadan önce yazılacak olan mesajdır.
19. satırdaki @After anotasyonu, hangi metotlardan sonra çalışacağını belirtir. Bu örneği detaylıca inceleyelim.
- execution anahtar kelimesinden hemen sonra gelen yıldız (*) simgesi herhangi bir dönüş tipi (return type) olabileceği anlamına gelir.
- Yıldızdan sonraki ilk kısım paket adı (com.metin.medium.aop.controller) daha sonra sınıf adı (*), bunun anlamı herhangi bir sınıf olabileceğidir. Ve son olarak metot adı (*) bunun anlamı herhangi bir metot olabileceğidir.
- Parantez içerisindeki iki nokta (..) simgesi, herhangi bir parametre olabileceği anlamına gelir.
21. satır, ilgili metotlar çalıştıktan sonra çalışacaktır.
24. satırdaki @Pointcut anotasyonu yapacağımız işlemlerin hangi metotlarla alakalı olduğunu belirtir. Fakat bu anotasyon kendi başına anlamlı değildir. Bu anotasyon; @After, @Before veya @AfterReturning gibi anotasyonların içerisinde kullanılır.
27. satırdaki @AfterReturning anotasyonunu detaylı olarak açıklayalım.
- Diğer kullanımlarda çift tırnak içerisinde execution anahtar kelimesini kullanarak başlıyordu. Bu örnekteyse pointcut = ile başlıyor. Yani tanımlanmış olan bir pointcut’ı kullanacağız.
- ikinci parametre olarak kullanılan returning ise dönen değeri metodun içerisinde hangi isimle kullanacağımızı gösterir. returning = “count”
28. satırdaki count parametresi, bir önceki satırdaki count değişkeninin değeridir.
30. satır, count değerini yazacaktır. Bu metodu tetiklemek için, http://localhost:8080/courses/count adresine istek atabilirsiniz.
Bir örnek daha yapalım. Bu örnek, authentication, authorization ile ilgili olacaktır.
AuthAspect adında bir sınıf ekliyoruz.
Bu örnekte, authentication ve authorization işlemlerinin yapılmasını istediğim sınıfları com.metin.medium.aop.controller.secured paketinin altına aldım.
Örneğin, http://localhost:8080/students/6 adresine bir istek gönderildiğinde önce AuthAspect sınıfındaki ilgili metotlar çalışacaktır. Daha sonra ilgili endpoint çalışacaktır.
Örneğin tamamına github adresimden ulaşabilirsiniz.
İyi günler,
Bol kodlamalar :)