Skip to content

16. Webapplicatie MVC in een 3-tier-architectuur – Voorbeeld 2

16.1. Introduction

We hebben de applicatie [personnes-01] geschreven met de volgende structuur:

De laag [dao] implementeerde de lijst met personen die werd beheerd met behulp van een object [ArrayList]. Hierdoor hoefden we ons niet te verdiepen in de lagen [dao] en [service], maar konden we ons concentreren op de laag [web]. We willen de applicatie verder ontwikkelen naar een meer realistische omgeving waarin de lijst met personen in een databasetabel wordt opgeslagen. Dit betekent dat we de laag [dao] moeten aanpassen. Dit heeft gevolgen voor de twee andere lagen. Om te profiteren van de onafhankelijkheid van de lagen die Spring IoC biedt, gaan we de applicatie [personnes-01] hergebruiken en deze configureren met Spring IoC:

De nieuwe applicatie krijgt de naam [personnes-02]. Zodra deze is geschreven, weten we dat we de lagen [dao] en [service] kunnen wijzigen zonder de code van de laag [web] te veranderen. Dat is precies wat we willen bereiken.

We maken een nieuw Eclipse-project [personnes-02] aan door het project [personnes-01] te kopiëren en te plakken, zoals uitgelegd in paragraaf 6.2:

In [1] verschijnt het configuratiebestand waarin we de beans van de lagen [dao] en [service] gaan definiëren. De inhoud ervan is als volgt:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!-- de DAO-klasse -->
    <bean id="dao" class="istia.st.mvc.personnes.dao.DaoImpl" init-method="init"/>
    <!-- de serviceklasse -->
    <bean id="service" class="istia.st.mvc.personnes.service.ServiceImpl">
        <property name="dao">
            <ref local="dao" />
        </property>
    </bean>
</beans>
  • regel 5: definieert de bean met de naam [dao] als een instantie van de klasse [DaoImpl]. Na het instantiëren wordt de methode [init] van de instantie uitgevoerd.
  • regels 7-10: definiëren de bean met de naam [service] als een instantie van de klasse [ServiceImpl].
  • regels 8-10: de eigenschap [dao] van de instantie [DaoImpl] wordt geïnitialiseerd met de referentie van de laag [dao] die in regel 5 is aangemaakt. Ter herinnering: de klasse [ServiceImpl] heeft inderdaad de eigenschap [dao] en de bijbehorende setter:
public class ServiceImpl implements IService {

     // de laag [dao]
    private IDao dao;

    public IDao getDao() {
        return dao;
    }

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

Dit bestand alleen doet natuurlijk nog niets. De controller [Application] zal het gebruiken in zijn methode [init] om de laag [service] te instantiëren. Laten we nog eens kijken naar de vorige versie van de methode [init] van de controller:

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

     // init
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
         // instantiëring van de laag [dao]
        DaoImpl dao = new DaoImpl();
        dao.init();
         // instantiëring van de laag [service]
        service = new ServiceImpl();
        service.setDao(dao);
    }

In regel 5 moesten we de implementatieklasse van de laag [service] expliciet benoemen en in regel 12 die van de laag [dao]. Met Spring IoC ziet de methode [init] er als volgt uit:

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

     // service
    private IService service = null;

     // init
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
    ...
         // instantie van de laag [service]
        service = (IService) new XmlBeanFactory(new ClassPathResource("spring-config.xml")).getBean("service");
    }
  • regel 7: het privéveld [service] heeft niet langer het type [ServiceImpl], maar het type [IService], c.a.d. van het type van de interface van de laag [service]. De laag [web] is dus niet langer gekoppeld aan een specifieke implementatie van deze interface.
  • regel 14: initialisatie van het veld [service] op basis van het configuratiebestand [spring-config.xml].

Dit zijn de enige wijzigingen die moeten worden aangebracht. Laten we deze nieuwe applicatie in Tomcat integreren, Tomcat starten en vervolgens de URL [http://localhost:8080/personnes-02] opvragen:

Image

16.2. Archivering van de webapplicatie

We hebben een Eclipse/Tomcat-project ontwikkeld voor een 3-tier-applicatie:

In een toekomstige versie zal de groep personen in een databasetabel worden opgeslagen.

  • Dit zal leiden tot een herschrijving van de laag [dao]. Dat is gemakkelijk te begrijpen.
  • Ook de laag [service] zal worden aangepast. Momenteel is de enige functie ervan het waarborgen van gesynchroniseerde toegang tot de gegevens die door de laag [dao] worden beheerd. Daartoe hebben we alle methoden van de laag [service] gesynchroniseerd. We hebben uitgelegd waarom deze synchronisatie in deze laag is ondergebracht in plaats van in de laag [dao]. In de nieuwe versie zal de laag [service] nog steeds uitsluitend de rol van synchronisatie van de toegang vervullen, maar deze zal worden gewaarborgd door databasetransacties in plaats van door synchronisatie van Java-methoden.
  • De laag [web] blijft ongewijzigd.

Om de overgang van de ene versie naar de andere te vergemakkelijken, maken we een nieuw Eclipse-project aan met de naam [mvc-personnes-02B], een kopie van het vorige project [mvc-personnes-02], maar waarbij de lagen [web, service, dao, entites] in .jar-archieven zijn ondergebracht:

De map [src] bevat nu alleen nog het Spring-configuratiebestand [spring-config.xml]. Voorheen bevatte deze map ook de broncode van de Java-klassen. Deze elementen zijn verdwenen en vervangen door hun gecompileerde versies, die zijn opgeslagen in de [personnes-*.jar]-archieven, weergegeven in [1]:

Het project [mvc-personnes-02B] is zo geconfigureerd dat het de archieven [personnes-*.jar ] opneemt in zijn ClassPath.

We implementeren het webproject [mvc-personnes-02B] in Tomcat:

Om het project te testen, starten we Tomcat op en roepen we vervolgens de URL [http://localhost:8080/personnes02B] op:

Image

De lezer wordt uitgenodigd om aanvullende tests uit te voeren.

In de versie met database gaan we de lagen [service] en [dao] wijzigen. We willen laten zien dat het dan voldoende is om in het vorige project de archieven [personnes-dao.jar] en [personnes-service.jar] te vervangen door de nieuwe archieven, zodat onze applicatie voortaan met een database werkt. We hoeven de bestanden van de laag [web] en de laag [entites] niet aan te raken.