AOP

Ciele

  1. Naučiť sa používať Aspektovo-orientované programovanie
  2. Naučiť sa používať nástroj AspectJ.

Postup

Krok 1: Pridanie modulu do zadania

Úloha 1.1

Pridajte Gradle podprojekt aspects do projektu vášho zadania.

Vytvorte adresár aspects a v ňom súbor build.gradle.kts:

plugins {
    id("java-library")
    id("io.freefair.aspectj") version "8.13.1"
}

group = "sk.tuke.meta"
version = "1.0-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

repositories {
    mavenCentral()
}

dependencies {
    api(project(":persistence"))
    api("org.aspectj:aspectjrt:1.9.23")
    testImplementation(platform("org.junit:junit-bom:5.9.1"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}

tasks.test {
    useJUnitPlatform()
}

Úloha 1.2

Použite aspekty z tohto projektu v projekte example.

Modifikujte example/build.gradle.kts tak, že upravíte sekcie plugins a dependencies:

plugins {
    id("application")
    id("io.freefair.aspectj.post-compile-weaving") version "8.13.1"
}

...

dependencies {
    aspect(project(":aspects"))
    ...

Krok 2: Prvý aspekt

Pre vyskúšanie práce s AspectJ vytvorme jednoduchý aspekt pre monitorovanie databázových operácií.

Úloha 2.1

Vytvorte súbor aspects/src/main/aspectj/sk/tuke/meta/persistence/DBMonitoring.aj.

Poznámka

Všimnite si, že namiesto src/main/java sa používa src/main/aspectj, keďže je to odlišný jazyk. Ďalej však nasleduje štruktúra adresárov zodpovedajúca balíkom, rovnako ako v Jave.

Obsah súboru nech je následovný:

package sk.tuke.meta.persistence;

import java.sql.Statement;

public aspect DBMonitoring {

    pointcut statementExecution(Statement stmt):
            call(* Statement+.execute*(..)) && target(stmt);

    before(Statement stmt): statementExecution(stmt) {
        System.out.println("Executing SQL: " + stmt);
    }
}

Úloha 2.2

Vyskúšajte spustiť projekt example a sledujte výpisy. Mali by sa tam objaviť výpisy všetkých vykonávaných SQL príkazov.

Úloha 2.3

Preštudujte si kód aspektu a snažte sa pochopiť jeho fungovanie.

Krok 3: @AspectJ

AspectJ ponúka aj alternatívny spôsob zápisu aspektov – pomocou Java tried s anotáciami. Môžete si vyskúšať aj tento zápis.

Úloha 3.1

Vytvorte súbor aspects/src/main/java/sk/tuke/meta/persistence/DBMonitoring2.java.

Poznámka

Teraz sa použil adresár src/main/java, keďže aspekt je definovaný pomocou Java triedy, ktorá je najprv prekladaná prekladačom Java a až následne pretkávaná pomocou AspectJ.

Číslo 2 v názve je len na odlíšenie od predchádzajúceho aspektu.

Obsah súboru nech je nasledovný:

package sk.tuke.meta.persistence;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.sql.Statement;

@Aspect
public class DBMonitoring2 {
    @Pointcut("call(* java.sql.Statement+.execute*(..)) && target(stmt)")
    public void statementExecution(Statement stmt) {}

    @Before("statementExecution(statement)")
    public void beforeStatementExecution(Statement statement) {
        System.out.println("Executing SQL: " + statement);
    }
}

Poznámka

Všimnite si, že v tomto zápise musia byť v bodových prierezoch použité úplné názvy tried (napr. java.sql.Statement).

Krok 4: Zadanie

Pre druhú úlohu zadania 3 potrebujete realizovať aspekt transakcií.

Úloha 4.1

Implementujte aspekt pre podporu transakcií podľa popisu v zadaní 3.

Aspekt sa naviaže na metódy označené anotáciou @AtomicPersistenceOperation (tu si musíte definovať), napríklad v projekte example (nie v persistence).