51
12.11.14 1 Komponenten – WS 2014/15 – Teil 11/Spring-DI Komponenten-basierte Entwicklung Teil 11: Spring - Dependency Injection

Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

12.11.14 1Komponenten – WS 2014/15 – Teil 11/Spring-DI

Komponenten-basierte Entwicklung

Teil 11: Spring - Dependency Injection

Page 2: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 2

Literatur

[11-1] Wolff, Eberhard: Spring 3. 3. Auflage, 2010, dpunkt

[11-2] Walls, Craig: Spring im Einsatz. 2. Auflage, 2012, Hanser

[11-3] http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf

[11-4] http://docs.spring.io/spring-framework/docs/current/

[11-5] Winterfeldt, David: Spring by Example.http://www.springbyexample.org/examples/index.html

[11-6] http://start.spring.io/

[11-7] http://maven-repository.com/archetypes

Page 3: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 3

Übersicht

• Konzept

• Hello-World: BigBean und SmallBean

• Setter-Injection mit Spring

• Mehrere Objekte derselben Klasse

• Constructor-Injection mit Spring

• Benutzung der eigenen Fabrik mit Setter-Injection

• Eigene Fabrik benutzt Spring

Page 4: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 4

Spring – was ist das?

• Spring ist ein Container für Komponenten, der neben Dependency Injection weitere Pakete integriert, z.B.

– Hibernate

– AOP (Aspect Oriented Programming)

– MVC-Web

• In diesen Teil wird nur der Kern des Dependency Injection beschrieben.

• Das Ziel besteht im automatisierten Aufbau von Objekt-Geflechten.

Page 5: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 5

Spring – was ist das? - Begriffe

• POJO = Plain Old Java Object = Java Klasse analog zu

• MOJO = Maven Old Java Object

• Bean = POJO = Java Klasse mit bestimmten Aufbau:

– Set-Methoden für die Setter-Injection

– Konstruktoren mit Parameter für die Constructor-Injection

• Container = Laufzeitumgebung einschließlich Management

• Diese Vorgaben führen zu recht viel Boilerplate-Code.

• Boilerplate = eigentlich: Kochplatte = notwendiger, teilweise umfangreicher Code mit trivialer SemantikTypisch:

– Try-Catch-Orgien

– Getter/Setter-Orgien

• Siehe: http://de.wikipedia.org/wiki/Boilerplate

Page 6: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 6

Spring – was ist das? - Struktur I

„Hauptprogramm“

Spring-DI

Spezifikation

call

read

In diesem Teil wird nur die XML-Datei basierte Version beschrieben.

Object 3

Object 1Object 4

Object 2

create

Page 7: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 7

Spring – was ist das? - Struktur II

• Spring-DI ist eigentlich nichts anderes als eine durch eine Datei gesteuerte Factory.

• Es gibt noch die neuere Version mit Annotationen.

• Die Aufgabe besteht im Erzeugen und Binden (Linking) von Objekten zu Objekt-Geflechten:

– Jedes Objekt wird als Singleton realisiert, so dass damit Beans/Klassen mit Funktionalität behandelt werden.

– Es können auch mehrere Exemplare realisiert werden, so dass damit Beans/Klassen mit Daten behandelt werden.

Page 8: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 8

Spring – was ist das? - Konzept

Klassen

Spring-DI

Spezifikation

call

read

KlassenKlassen

SpezifikationSpezifikation

Objecterealize

container

Es wird ähnlich wie bei Mavenein Lifecycle realisiert.

Page 9: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 9

Maven und Spring I

<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <spring.version>4.1.1.RELEASE</spring.version> … … …</properties>

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version></dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version></dependency>

Page 10: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 10

Maven und Spring II

<properties> … … … <package.name>de.htw_berlin.f4.kbe.spring</package.name> <main.name>App</main.name></properties>

… … … <artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration> <archive> <manifest> <mainClass>${package.name}.${main.name}</mainClass> <addClasspath>true</addClasspath> </manifest> </archive></configuration>… … …

Page 11: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 11

Zwei Objekte werden verknüpft I - BigBean

public class BigBean { private SmallBean myBean; private int intProperty; BigBean() { System.out.println("*BIG bean is made*"); } public SmallBean getMyBean() { return myBean; } public void setMyBean(SmallBean myBean) { this.myBean= myBean; } public int getIntProperty() { return intProperty; } public void setIntProperty(int intProperty) { this.intProperty= intProperty; }}

Page 12: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 12

Zwei Objekte werden verknüpft II - SmallBean

public class SmallBean { private String myName; SmallBean() { System.out.println("*small bean is made*"); } public String getMyName() { return myName; } public void setMyName(String myName) { this.myName= myName; }}

Page 13: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 13

Zwei Objekte werden verknüpft III - Spring

<?xml version="1.0" encoding="UTF-8"?><beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

<bean id="IDBigBean" class="de.htw_berlin.f4.kbe.spring.BigBean"> <property name="intProperty"> <value>42</value> </property> <property name="myBean"> <ref bean="IDSmallBean"/> </property> </bean>

<bean id="IDSmallBean" class="de.htw_berlin.f4.kbe.spring.SmallBean"> <property name="myName"> <value>Ich bin das kleine Beanchen</value> </property> </bean> </beans>

Datei BigSmallBeans.xml

Page 14: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 14

Erläuterungen I

<bean id="IDBigBean" class="de.htw_berlin.f4.kbe.spring.BigBean">

<property name="intProperty"> <value>42</value> </property>

<property name="myBean"> <ref bean="IDSmallBean"/> </property>

Name der Klassein Spring

Name der Klassein Java

Name desAttributs in Java

Wert desAttributs

Name desAttributs in Java

Referenz aufSpring Bean

Page 15: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 15

Erläuterungen II

• Bei den einfachen Attributen wird mit der setter-Injektion gearbeitet: Entsprechend der Namenskonvention werden die set-Methoden mit dem Parameter versehen

• Bei Attributen mit einer Referenz erfolgt dasselbe.

Page 16: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 16

Zwei Objekte werden verknüpft IV - Hauptprogramm

import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App { public static void main(String[] args) { System.out.println("Hello Beans!"); ApplicationContext appContext= new ClassPathXmlApplicationContext("BigSmallBeans.xml"); BigBean big= (BigBean) appContext.getBean("IDBigBean"); SmallBean small= big.getMyBean(); System.out.println("big.getIntProperty()= "+big.getIntProperty()); System.out.println("small.getMyName() = "+small.getMyName()); }}

Page 17: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 17

Erläuterungen

ApplicationContext appContext= new ClassPathXmlApplicationContext("BigSmallBeans.xml")

Name der Spring-Konfigurationsdatei

BigBean big= (BigBean) appContext.getBean("IDBigBean");

Es wird ein Container für das Objekt-Geflecht eingerichtet.

Basierend auf der Container-Initialisierung wird das Geflecht in Form eines Singletons aufgebaut und initialisiert.

Name der Klassein Spring

Page 18: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 18

Zwei Objekte werden verknüpft V - Output

Hello Beans!Nov 10, 2014 8:43:25 PM org.springframework.... prepareRefreshINFORMATION: Refreshing org.springframework....: startup date … Nov 10, 2014 8:43:25 PM org.springframework.... loadBeanDefinitionsINFORMATION: Loading XML bean definitions ... [BigSmallBeans.xml]*BIG bean is made**small bean is made*big.getIntProperty()= 42small.getMyName() = Ich bin das kleine Beanchen

Output

Page 19: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 19

Netbeans Integration

Klassen – wie immer

Konfigurationsdateien

POM und netbeans-Konfiguration

Page 20: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 20

Variation I – Ort der XML-Datei

ClassPathXmlApplicationContext("BigSmallBeans.xml");

XML-Datei muss ander Target-Wurzel liegen.

ClassPathXmlApplicationContext("de/htw_berlin/f4/kbe/spring/BigSmallBeans.xml");

XML-Datei muss im Klassen-Ordner liegen.

Page 21: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 21

Variation II – Ort der XML-Datei

Es kann auch der absolute Pfad zur XML-Datei angegeben werden.

import org.springframework.context.support.FileSystemXmlApplicationContext;… … … String fn= "D:/bmesser/.../Spring-01/target/classes/BigSmallBeans.xml";ApplicationContext appContext= new FileSystemXmlApplicationContext(fn);

Page 22: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 22

Singleton

• Singleton = Objekt, das nur ein einziges Mal erzeugt werden kann

• Spring erzeugt per Default nur Singletons ohne dass das Singelton-Muster benutzt wird.

• Siehe:

– http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

– http://de.wikipedia.org/wiki/Liste_von_Singleton-Implementierungen

BigBean big= (BigBean) appContext.getBean("IDBigBean");...BigBean big2= (BigBean) appContext.getBean("IDBigBean");System.out.println("Dieselben Objekte? "+(big==big2));

Output

Dieselben Objekte? true

Page 23: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 23

Der Event Manager noch einmal I

Location DescriptionEventAppointment

• Location: Liste der Orte

• Event: Liste der Aktivitäten

• Description: Beschreibung der Aktivität

• Appointment: Zusammenfassung samt Datum und Uhrzeit

• Es werden alle Klassen systematisch mit getXXX/setXXX()-Methoden versehen.

• Es werden alle Konstruktoren auf den Standard-Konstruktor ohne Parameter reduziert.

Page 24: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 24

Der Event Manager noch einmal II

public class Event { EventType mode; Description description; public void setMode(EventType mode) { this.mode= mode; } public EventType getMode() { return this.mode; } public void setDescription(Description description) { this.description= description; } public Description getDescription() { return this.description; }}

Hier nur als Beispiel die Klasse Event.

Page 25: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 25

Der Event Manager noch einmal III

public class Appointment { String date; String time; Location location; Event event; public void setLocation(Location location) { this.location= location; } public void setEvent(Event event) { this.event= event; } public String getStreet() { return location.getStreet(); } public void setStreet(String street) { location.setStreet(street); }

Dies ist der 1. Teil von Appointment.Mit den get/set-Methoden wird der innere Aufbau verdeckt.

Routinen, dievon Springbeim Zusammen-bau aufgerufenwerden.

Page 26: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 26

Der Event Manager noch einmal IV

public EventType getMode() { return event.getMode(); } public void setMode(EventType mode) { event.setMode(mode); } public String getDescription() { return event.getDescription().getDescription(); } public void setDescription(String text) { event.getDescription().setDescription(text); }} Bei jedem Zwischenschritt

eines Zugriffs werdendie get/set-Routinen benutzt.

Dies ist der 2. Teil von Appointment (Auszug).

Page 27: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 27

Der Event Manager noch einmal V - XMLContext

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment"> <property name="location"> <ref bean="IDLocation"/> </property> <property name="event"> <ref bean="IDEvent"/> </property> <property name="street"> <value>Müllerstr.</value> </property> <property name="houseNumber"> <value>12a</value> </property> <property name="city"> <value>Berlin</value> </property> <property name="postalCode"> <value>11089</value> </property> <property name="mode"> <value>BIRTHDAY</value> </property> <property name="description"> <value>Geburtstag ...</value> </property> <property name="date"> <value>10. Mai 2012</value> </property> <property name="time"> <value>19:00</value> </property></bean><bean id="IDLocation" class="de.htw_berlin.f4.kbe.spring.Location"/><bean id="IDEvent" class="de.htw_berlin.f4.kbe.spring.Event"> <property name="description"> <ref bean="IDDescription"/> </property></bean> <bean id="IDDescription" class="de.htw_berlin.f4.kbe.spring.Description"/>

Auszug aus der XML-DateiEs werden alle Attribute über die Zugriffsfunktionen von Appointment gesetzt

Page 28: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 28

Der Event Manager noch einmal VI

public class EventManager { Appointment[] apps; EventManager() { apps= new Appointment[10]; ApplicationContext appContext= new ClassPathXmlApplicationContext("Feten.xml"); apps[0]= (Appointment) appContext.getBean("IDApps"); } protected void printAppointments() { for(Appointment app : apps) { if(app!=null) { System.out.printf( "Am %s %s: %s Ort %s %s %s %s ist %s\n", app.getDate(),app.getTime(), app.getMode(), app.getStreet(), app.getHouseNumber(),app.getPostalCode(), app.getCity(), app.getDescription());}}}}

Das „Hauptprogramm“; die Initialisierung erfolgt über Spring.

Page 29: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 29

Der Event Manager noch einmal VII

• Damit ist ein Satz von Objekten erzeugt und vorbelegt.

• Per XML ist das nur für ein Geflecht möglich.

• D.h. wir bauen um...

Output

Liste der Feten 2012Nov 11, 2014 3:39:59 PM org.springframework.context....INFORMATION: Refreshing org.springframework.context....Nov 11, 2014 3:39:59 PM org.springframework.beans.factory.xml....INFORMATION: Loading XML bean definitions from ... [Feten.xml]Am 10. Mai 2012 19:00: BIRTHDAY Ort Müllerstr. 12a 11089 Berlin ist ...

Page 30: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 30

Events zum Dritten I

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment"> <property name="location"> <ref bean="IDLocation"/> </property> <property name="event"> <ref bean="IDEvent"/> </property></bean>

<bean id="IDLocation" class="de.htw_berlin.f4.kbe.spring.Location"/>

<bean id="IDEvent" class="de.htw_berlin.f4.kbe.spring.Event"> <property name="description"> <ref bean="IDDescription"/> </property></bean>

<bean id="IDDescription" class="de.htw_berlin.f4.kbe.spring.Description"/>

Das Setzen der Daten wird aus der XML-Datei entfernt und es ineine Art „Loader“ in Appointment verschoben.

Page 31: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 31

Events zum Dritten II

public class EventManager { Appointment[] apps; EventManager() { apps= new Appointment[10]; init(); } private void init() { ApplicationContext appContext= new ClassPathXmlApplicationContext("Feten.xml"); apps[0]= (Appointment) appContext.getBean("IDApps"); apps[0].setStreet("Müllerstr."); apps[0].setHouseNumber("12a"); apps[0].setCity("Berlin"); apps[0].setPostalCode("11089"); apps[0].setMode(EventType.BIRTHDAY); apps[0].setDescription("Geburtstag des grossen Vorsitzenden"); apps[0].setDate("10. Mai 2012"); apps[0].setTime("19:00");

Der 1. Teil

Page 32: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 32

Events zum Dritten II

apps[1]= (Appointment) appContext.getBean("IDApps"); apps[1].setStreet("Karl-May-Allee"); apps[1].setHouseNumber("110"); apps[1].setCity("Berlin"); apps[1].setPostalCode("12017"); apps[1].setMode(EventType.BOOZY_PARTY); apps[1].setDescription("Gelage bei Willi"); apps[1].setDate("1. April 2012"); apps[1].setTime("18:00"); }

Der 2. Teil

Output

Liste der Feten 2012Nov 11, 2014 3:49:12 PM org.springframework.....INFORMATION: Refreshing org.springframework.....Nov 11, 2014 3:49:12 PM org.springframework.....INFORMATION: Loading XML bean definitions from... [Feten.xml]Am 1. April 2012 18:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 Berlin ...Am 1. April 2012 18:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 Berlin ...

Und das ist falsch.

Page 33: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 33

Events zum Dritten III

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment" scope="prototype"> <property name="location"> <ref bean="IDLocation"/> </property> <property name="event"> <ref bean="IDEvent"/> </property></bean>

Mit diesem Attribute wird jeweils ein neues Objekt geschaffen.

Output

Am 10. Mai 2012 19:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 Berlin ist ...Am 1. April 2012 18:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 Berlin ist ...

Immer noch falsch.

Richtig, da Appointmentdupliziert wird.

Page 34: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 34

Events zum Dritten IV

EventManager

Appoint-ment

Event

Location

Description

EventManager

Appoint-ment

Event

Location

Description

Appoint-ment

Vorher (Falsch)

Nachher (Falsch)

Alles benötigt scope=“prototype“.

Page 35: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 35

Events zum Dritten V

Am 10. Mai 2012 19:00: BIRTHDAY Ort Müllerstr. 12a 11089 Berlin ist ...Am 1. April 2012 18:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 ...

EventManager

Appoint-ment

Event

Location

DescriptionNun richtig.

Appoint-ment

Event

Location

Description

Output

Das ist der Unterschiedzwischen dem flachenund dem tiefen Klonen.

Page 36: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 36

Eine Variation – Constructor Injection I

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment"scope="prototype">

<constructor-arg ref="IDLocation"/> <constructor-arg ref="IDEvent"/></bean><bean id="IDLocation" class="de.htw_berlin.f4.kbe.spring.Location"

scope="prototype"/><bean id="IDEvent" class="de.htw_berlin.f4.kbe.spring.Event"

scope="prototype"> <constructor-arg ref="IDDescription"/></bean> <bean id="IDDescription" class="de.htw_berlin.f4.kbe.spring.Description"

scope="prototype"/>

Anstatt mit setXXX() die Verknüpfungen zu realisieren, werden diese mit dem Konstruktor gesetzt.Daher müssen die Klassen Appointment und Event geändert werden.

Page 37: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 37

Eine Variation – Constructor Injection II

public class Appointment { String date; String time; Location location; Event event; Appointment(Location location,Event event) { this.location= location; this.event= event; } public void setDate(String date) { this.date= date; } public String getDate() { return this.date; }… … …

Der Konstruktor erwartet die Referenzen auf die anderen Objekte. Anhand des Typs erkennt Spring, was zu welchem Parameter gehört.

Page 38: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 38

Eine Variation – Constructor Injection III

public class Event { EventType mode; Description description; Event(Description description) { this.description= description; } public void setMode(EventType mode) { this.mode= mode; }… … …

Page 39: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 39

Eine Variation – Eigene Fabrik I

public class Appointment extends AbstractAppointment { static AppointmentCreation factory;

Appointment(Location location, Event event) { super(location,event); } Appointment() { } public static void setFactory(AppointmentCreation newFactory) { factory= newFactory; }

• Es wird die alte Implementierung aus der Einheit über Dependency Injection genommen.

• Dort gab es zwei Factories, die über ein statisches Attribut innerhalb der Klasse Appointment aufgerufen werden.

• Dieses Attribut wird nun per Setter-Injektion mit Spring gesetzt.

1. Teil vonAppointment

Set-Routine für Spring

Page 40: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 40

Eine Variation – Eigene Fabrik II

public static Appointment newObject(int record) { Appointment app= factory.createAppointment(); switch (record) { case 0: app.setStreet("Müllerstr."); app.setHouseNumber("12a"); app.setCity("Berlin"); app.setPostalCode("11089"); app.setMode(EventType.BIRTHDAY); app.setDescription("Geburtstag des grossen Vorsitzenden"); app.setDate("10. Mai 2012"); app.setTime("19:00"); break; case 1: … … … } return app;}}

2. Teil vonAppointment

Aufruf derFactory

Page 41: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 41

Eine Variation – Eigene Fabrik III

public class EventManager { Appointment[] apps; EventManager() { apps= new Appointment[10]; ApplicationContext appContext= new ClassPathXmlApplicationContext("Feten_Factory.xml"); apps[0]= (Appointment) appContext.getBean("IDApps"); apps[0]= Appointment.newObject(0); apps[1]= Appointment.newObject(1); }… … …

Aufruf derFactory

Injection

public class App { public static void main( String[] args ) { System.out.println("Liste der Feten 2012"); EventManager ev= new EventManager(); ev.printAppointments(); }}

Hier das gleiche„Hauptprogramm“

Page 42: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 42

Eine Variation – Eigene Fabrik IV

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment"> <property name="factory"> <ref bean="IDFactory"/> </property></bean><bean id="IDFactory" class="de.htw_berlin.f4.kbe.spring.AppointmentFactory"/><bean id="IDAltFactory" class="de.htw_berlin.f4.kbe.spring.AppointmentAlternativeFactory"/>

Output

Liste der Feten 2012Nov 11, 2014 6:04:43 PM org.springframework....INFORMATION: Refreshing org.springframework....Nov 11, 2014 6:04:43 PM org.springframework....INFORMATION: Loading XML bean definitions from ... [Feten_Factory.xml]AppointmentFactory is usedAppointmentFactory is usedAm 10. Mai 2012 19:00: BIRTHDAY Ort Müllerstr. 12a 11089 Berlin ist ...Am 1. April 2012 18:00: BOOZY_PARTY Ort Karl-May-Allee 110 12017 Berlin ...

Page 43: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 43

Bemerkungen I

• newObject() ist eine statische Routine, die über eine statische Referenzvariable factory aufgerufen wird.

• Daher wird bei Appointment nicht mit scope=“prototype“ gearbeitet, denn aus der Sicht von Spring ist Appointment ein Singleton.

• In diesem Singleton erzeugt die eigene Factory newObject() per new() neue Instanzen.Oder anders formuliert: Die (nicht-statische) Klasse Appointment hat eine eigene statische Factory, um eine Instanz von sich selbst zu erzeugen.

• Factories werden grundsätzlich nur einmal instanziiert.

Diese Konstruktion ist ein bischen tricky...

Page 44: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 44

Bemerkungen II

Datei fürProduktion

Datei für dasTesten (mit Mocks)

Je nach Anwendungsfall wird eine andereFabrik-Methode gewählt.

Page 45: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 45

Noch eine Variation – Eigene Fabrik I

Es ist auch möglich, dass Spring die Factory angegeben wird:

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment" factory-method="newObject" scope="prototype"></bean>

Oder eben:

<bean id="IDApps" class="de.htw_berlin.f4.kbe.spring.Appointment" factory-method="newObjectAlternate" scope="prototype"></bean>

Dazu muss es zwei Factory-Methoden geben.Wir bauen das Programm um...

Page 46: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 46

Noch eine Variation – Eigene Fabrik II

public class Appointment extends AbstractAppointment { static AppointmentCreation factoryNormal= new AppointmentFactory(); static AppointmentCreation factoryAltern= new AppointmentAlternativeFactory();

Appointment(Location location, Event event) { super(location,event); } Appointment() { } public static Appointment newObject() { return factoryNormal.createAppointment(); } public static Appointment newObjectAlternate() { return factoryAltern.createAppointment(); }}

Wir entfernen die Initialisierung und definieren zwei Erzeugungsmethoden.

Die beidenFactories

Hier werdensie erzeugt

Page 47: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 47

Noch eine Variation – Eigene Fabrik III

public class EventManager { Appointment[] apps; EventManager() { apps= new Appointment[10]; ApplicationContext appContext= new ClassPathXmlApplicationContext("Feten_Factory.xml"); apps[0]= (Appointment) appContext.getBean("IDApps"); init(apps[0], 0); apps[1]= (Appointment) appContext.getBean("IDApps"); init(apps[1], 1); }

Spring ruft jetzt die Factory-Methoden auf.Bitte beachten: scope=“prototype“.

Hier werdensie erzeugt

1. Teil

Page 48: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 48

Noch eine Variation – Eigene Fabrik IV

private void init(Appointment app, int record) { switch (record) { case 0: app.setStreet("Müllerstr."); app.setHouseNumber("12a"); app.setCity("Berlin"); app.setPostalCode("11089"); app.setMode(EventType.BIRTHDAY); app.setDescription("Geburtstag des grossen Vorsitzenden"); app.setDate("10. Mai 2012"); app.setTime("19:00");… … …

Das ist die heraus gezogene Initialisierungsroutine, dienun als Parameter ein Appointment-Objekt erhält.

2. Teil

Page 49: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 49

Neugier I

DumpTree dump= new DumpTree();apps= new Appointment[10];ApplicationContext appContext = new ClassPathXmlApplicationContext("Feten_Factory.xml");apps[0]= (AbstractAppointment) appContext.getBean("IDApps");init(apps[0], 0);dump.showObject(apps[0]);apps[1]= (AbstractAppointment) appContext.getBean("IDApps");init(apps[1], 1);dump.showObject(apps[1]);… … …

Auszug ausEventManager

Als neugierige Menschen schauen wir uns genau an, was Springeigentlich gemacht hat.Dazu schreiben wir uns eine kleine Dump-Klasse, die das Objekt-geflecht traversiert und „graphisch“ ausgibt.

Page 50: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 50

Neugier II - Ausgabe

Appointment AppointmentCreation factoryNormal= @62ee68d8 | +>AppointmentFactory AppointmentCreation factoryAltern= @58651fd0 | +>AppointmentAlternativeFactory String date= '10. Mai 2012' String time= '19:00' Location location= @5419f379 | +>Location String street= 'Müllerstr.' String houseNumber= '12a' String city= 'Berlin' String postalCode= '11089' Event event= @d2cc05a | +>Event EventType mode= [BIRTHDAY] Description description= @548a9f61 | +>Description String text= 'Geburtstag des grossen Vorsitzenden'

Das ist die Ausgabe des ersten Aufrufs

Einen Preis bekommtdas nicht – aber eserfüllt die Aufgabe

Page 51: Komponenten-basierte Entwicklung Teil 11: Spring ...wi.f4.htw-berlin.de/users/messer/LV/AI-KBE-WS14/Folien/KBE-11/11-… · Komponenten – WS 2014/15 – Teil 11/Spring-DI 12.11.14

Komponenten – WS 2014/15 – Teil 11/Spring-DI 51

Nach dieser Anstrengung etwas Entspannung...