Zadanie 3 — generovanie kódu a AOP

Ciele

  1. Precvičiť generovanie kódu počas kompilácie aplikácie.
  2. Naučiť sa používať aspektovo-orientované programovanie a AspectJ.

Úloha 1: Generovanie kódu

Aby sme optimalizovali prácu našej knižnice, presunieme čo najviac operácii do fázy prekladu. Okrem SQL príkazov na vytvárania tabuliek, budeme generovať aj zdrojový kód pre načítavanie a ukladanie jednotlivých typov entít.

Pomocou anotačného procesora vygenerujte pre každý entítny typ novú triedu, ktorá bude zabezpečovať perzistenciu práve tohto typu — data access object (DAO). Vygenerujte tiež novú implementáciu rozhrania PersistenceManager, ktorá bude len na základe typu argumentu volať metódy príslušného DAO. Táto trieda musí byť nazvaná GeneratedPersistenceManager.

Využívajte možnosti oddelenia všeobecného kódu od špecifického. Napríklad umiestnéte všeobecný kód do abstraktných tried, od ktorých budú generované triedy dediť.

Úloha 2: Podpora transakcií

V kóde, ktorý bude používať našu knižnicu môže byť potrebné použiť transakcie. Napríklad ak niekoľko operácií nad databázou spolu súvisa a musia sa teda vykonať naraz, inak by sa databáza na chvíľu dostala do nekonzistentného stavu.

Definujte anotáciu @AtomicPersistenceOperation v balíku sk.tuke.meta.persistence.annotations pomocou ktorej bude možné označiť používateľské metódy, ktoré budú zodpovedať jednej transakcii.

Pomocou AspectJ implementujte riešenie, ktoré automaticky vytvori transakciu pre takto označené metódy. Na konci ich vykonania metódy sa vykoná commit alebo rollback podľa toho, či metóda vyhodila výnimku. Nekonzistenciu hodnôt objektov po rollbacku riešiť netreba.

Poznámka

Pre jednoduchosť môžeme predpokladať, že v aplikácii bude existovať iba jedna inštancia triedy PersistenceManager. Pomocou aspektu môžete zachytiť vytváranie tejto inštancie.

Organizácia projektu

Pridajte nový modul pre aspekty s názvom aspects. Jeho build.gradle.kts môže vyzerať následovne:

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

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

repositories {
    mavenCentral()
}

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

}

tasks.test {
    useJUnitPlatform()
}

Projekt example tiež potrebujete upraviť. Jednák zapnúť podporu AspectJ:

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

A tiež pridať závislosť na aspekte:

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

Odovzdanie

Zadanie je potrebné vypracovať v priradenom projekte v Gitlabe do konca 5. mája.