Skip to content

16. Webanwendung MVC in einer 3-Tier-Architektur – Beispiel 2

16.1. Einleitung

Wir haben die Anwendung [personnes-01] mit folgender Struktur geschrieben:

Die Schicht [dao] implementierte die Liste der Personen, die mithilfe eines Objekts [ArrayList] verwaltet wurde. Dadurch konnten wir uns nicht mit den Schichten [dao] und [service] befassen und uns stattdessen auf die Schicht [web] konzentrieren. Wir möchten die Anwendung in eine realistischere Umgebung weiterentwickeln, in der die Liste der Personen in einer Datenbanktabelle gespeichert wird. Dies wird uns dazu veranlassen, die Schicht [dao] zu ändern. Dies wird sich auf die beiden anderen Schichten auswirken. Um die durch Spring IoC ermöglichte Unabhängigkeit der Schichten zu nutzen, werden wir die Anwendung [personnes-01] übernehmen und sie mit Spring IoC konfigurieren:

Die neue Anwendung wird den Namen [personnes-02] tragen. Sobald sie fertiggestellt ist, wissen wir, dass wir die Schichten [dao] und [service] ändern können, ohne den Code der Schicht [web] zu ändern. Genau das ist unser Ziel.

Wir erstellen ein neues Eclipse-Projekt [personnes-02] durch Kopieren und Einfügen des Projekts [personnes-01], wie in Abschnitt 6.2 erläutert:

In [1] erscheint nun die Konfigurationsdatei, in der wir die Beans der Schichten [dao] und [service] definieren werden. Ihr Inhalt lautet wie folgt:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!-- die DAO-Klasse -->
    <bean id="dao" class="istia.st.mvc.personnes.dao.DaoImpl" init-method="init"/>
    <!-- die Serviceklasse -->
    <bean id="service" class="istia.st.mvc.personnes.service.ServiceImpl">
        <property name="dao">
            <ref local="dao" />
        </property>
    </bean>
</beans>
  • Zeile 5: Definiert die Bean mit dem Namen [dao] als Instanz der Klasse [DaoImpl]. Nach der Instanziierung wird die Methode [init] der Instanz ausgeführt.
  • Zeilen 7–10: Definieren die Bean mit dem Namen [service] als Instanz der Klasse [ServiceImpl].
  • Zeilen 8–10: Die Eigenschaft [dao] der Instanz [DaoImpl] wird mit der Referenz der in Zeile 5 angelegten Schicht [dao] initialisiert. Zur Erinnerung: Die Klasse [ServiceImpl] verfügt tatsächlich über die Eigenschaft [dao] und den dazugehörigen Setter:
public class ServiceImpl implements IService {

    // die Schicht [dao]
    private IDao dao;

    public IDao getDao() {
        return dao;
    }

    public void setDao(IDao dao) {
        this.dao = dao;
    }
...

Diese Datei allein bewirkt natürlich noch nichts. Der Controller [Application] wird sie in seiner Methode [init] verwenden, um die Schicht [service] zu instanziieren. Erinnern wir uns an die vorherige Version der Methode [init] des Controllers:

@SuppressWarnings("serial")
public class Application extends HttpServlet {
...
    // Dienst
    ServiceImpl service = null;

    // Initialisierung
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
        // Instanziierung der Schicht [dao]
        DaoImpl dao = new DaoImpl();
        dao.init();
        // Instanziierung der Schicht [service]
        service = new ServiceImpl();
        service.setDao(dao);
    }

In Zeile 5 mussten wir die Implementierungsklasse der Schicht [service] explizit benennen, und in Zeile 12 die der Schicht [dao]. Mit Spring IoC sieht die Methode [init] wie folgt aus:

@SuppressWarnings("serial")
public class Application extends HttpServlet {
    // Instanzparameter
    ...

    // Dienst
    private IService service = null;

    // Init
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
    ...
        // Instanziierung der Schicht [service]
        service = (IService) new XmlBeanFactory(new ClassPathResource("spring-config.xml")).getBean("service");
    }
  • Zeile 7: Das private Feld [service] hat nicht mehr den Typ [ServiceImpl], sondern den Typ [IService], c.a.d. vom Typ der Schnittstelle der Schicht [service]. Die Schicht [web] ist somit nicht mehr an eine bestimmte Implementierung dieser Schnittstelle gebunden.
  • Zeile 14: Initialisierung des Feldes [service] anhand der Konfigurationsdatei [spring-config.xml].

Dies sind die einzigen Änderungen, die vorgenommen werden müssen. Binden wir diese neue Anwendung in Tomcat ein, starten wir Tomcat und rufen wir die URL [http://localhost:8080/personnes-02] auf:

Image

16.2. Archivierung der Webanwendung

Wir haben ein Eclipse-/Tomcat-Projekt für eine 3-Tier-Anwendung entwickelt:

In einer kommenden Version wird die Personengruppe in einer Datenbanktabelle abgelegt.

  • Dies wird eine Neuprogrammierung der Schicht [dao] erfordern. Das ist leicht nachvollziehbar.
  • Auch die Schicht [service] wird geändert. Derzeit besteht ihre einzige Aufgabe darin, einen synchronisierten Zugriff auf die von der Schicht [dao] verwalteten Daten zu gewährleisten. Zu diesem Zweck haben wir alle Methoden der Schicht [service] synchronisiert. Wir haben erläutert, warum diese Synchronisation in dieser Schicht und nicht in der Schicht [dao] platziert wurde. In der neuen Version wird die Schicht [service] weiterhin ausschließlich der Synchronisation des Zugriffs dienen, diese wird jedoch durch Datenbanktransaktionen statt durch eine Synchronisation von Java-Methoden gewährleistet.
  • Die Schicht [web] bleibt hingegen unverändert.

Um den Übergang von einer Version zur anderen zu erleichtern, erstellen wir ein neues Eclipse-Projekt [mvc-personnes-02B], das eine Kopie des vorherigen Projekts [mvc-personnes-02] ist, bei dem jedoch die Schichten [web, service, dao, entites] in .jar-Archive gepackt wurden:

Der Ordner [src] enthält nun nur noch die Spring-Konfigurationsdatei [spring-config.xml]. Zuvor enthielt er auch den Quellcode der Java-Klassen. Diese Elemente sind verschwunden und wurden durch ihre kompilierten Versionen ersetzt, die in den in [1] gezeigten Archiven [personnes-*.jar] abgelegt wurden:

Das Projekt [mvc-personnes-02B] wurde so konfiguriert, dass es die Archive [personnes-*.jar ] in sein ClassPath einbindet.

Wir stellen das Webprojekt [mvc-personnes-02B] in Tomcat bereit:

Um das Projekt zu testen, starten wir Tomcat und rufen dann die URL [http://localhost:8080/personnes02B] auf:

Image

Der Leser ist aufgefordert, weitere Tests durchzuführen.

In der Version mit Datenbank werden wir die Schichten [service] und [dao] ändern. Wir möchten zeigen, dass es dann ausreicht, im vorherigen Projekt die Archive [personnes-dao.jar] und [personnes-service.jar] durch die neuen Archive zu ersetzen, damit unsere Anwendung nun mit einer Datenbank funktioniert. An den Archiven der Schichten [web] und [entites] müssen wir keine Änderungen vornehmen.