Programowanie zorientowane aspektowo (AOP) to podejście do programowania, które umożliwia przechwycenie działań wskazanej metody, w celu uruchomieniu jakiegoś fragmentu kodu przed lub po logice wykonującej się w przechwytywanej metodzie.
Przykład
Przykładowo jest metoda foo, której zadaniem jest zapis informacji i wyświetlenie komunikatu o zapisaniu. W tradycyjnym podejściu jedną metodę zapisuje się jedna pod drugą.
public void foo() {
save();
System.out.println("saved");
}
W AOP dąży się do czystości kodu, poprzez izolacje odpowiedzialności. Metody robią to tylko za co są odpowiedzialne, nie miesza się logik jakimi są zapisywanie i wypisywanie informacji w oknie konsoli.
W podejściu AOP metoda foo zapisuje jedynie informacje. Inna metoda odpowiedzialna za wypisywanie tekstu na ekranie nasłuchuje metodę foo i kiedy foo skończyło swoją pracę to metoda nasłuchująca wykonuje swoje działanie.
Implementacja
Zależnością jaką trzeba dodać do projektu jest:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Zależność umożliwia na między innymi na wykorzystanie trzech kluczowych porad, które w parametrze przyjmują ścieżkę do metody jaka ma zostać przechwycona:
- @Around – Metoda oznaczona tą adnotacją wykona się przed lub zamiast metody wskazanej w parametrze.
- @Before – Metoda oznaczona tą adnotacją wykona się przed metodą wskazaną w parametrze.
- @After – Metoda oznaczona tą adnotacją wykona się po metodzie wskazanej w parametrze.
Metoda, którą chcemy przechwycić to metoda sayHello
public String sayHello() {
return "Hello " + "";
}
Żeby stworzyć możliwość jej przechwycenia trzeba utworzyć klasę z adnotacjami:
- @Aspect
- @Component
@Aspect
@Component
public class HelloAspect {
@Around("@annotation(Hello)")
public void aroundHello(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("aroundHello");
joinPoint.proceed();
}
@Before("@annotation(Hello)")
public void beforeHello() {
System.out.println("beforeHello");
}
@After("execution(String pl.bykowski.springbootaop.HelloApi.sayHello())")
public void afterHello() {
System.out.println("afterHello");
}
}
W poniższym przypadku zostały zaimplementowane trzy metody (zwane również poradami). W przypadku wywołania metody sayHello kolejno uruchomią się metody:
- aroundHello
- beforeHello
- sayHello
- afterHello
Warto zwrócić uwagę, że porada @Around przyjmuje w parametrze ProceedingJoinPoint. Dzięki temu, możliwe jest przekazanie wątku dalej do metody przechwytywanej. Bez wywołania joinPoint.proceed() to metoda przechwytywana nie wykonałaby się. Takie działanie może mieć swoje uzasadnienie w wybranych przypadkach.
Podsumowanie
Programowanie zorientowane aspektowo pozwala zachować czytelność kodu. Jednak odbywa się to kosztem zaburzenia naturalnego przepływu działania programu i jest w sprzeczności z zasadami programowania obiektowego. Dlatego należy stosować AOP rozsądnie i przemyślanie. Najczęściej wykorzystuje się go do logowania informacji lub zabezpieczeń.
Szkolenia live dla developerów • praktyczna wiedza, realne case’y, zero lania wody 

