Spring Framework
Jens Rühmkorf
Tech Talk, DLR Köln-Porz, 17. März 2009
Inhalt


  Überblick und Einführung
  Grundlegende Prinzipien
  Funktionsweise eines DI-Frameworks am Beispiel
  Beans & i...
Überblick und Einführung
Spring Framework
Geschichte

  Begonnen 2002/2003 von Rod Johnson und Jürgen Höller
  Spring 1.0: März 2004
  Spring 1.2.6...
Spring Framework
Anforderungen an die Systemumgebung

  Spring 2.5 läuft auf JavaSE 6 und JavaEE 5
  Für bestimmte Konfigu...
Übersicht des Spring Frameworks
http://static.springframework.org/spring/docs/2.5.x/reference/




                       ...
Spring Hello (1)              class HelloWorld


Hello World!                    -
                                       ...
Spring Hello (2)
Main
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
 ...
Spring Hello (3)
The Glue
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="[...]" xmlns:schemaLoca...
Spring Hello (4)
Ausgabe
17.03.2009 15:06:45 org.springframework.context.support.AbstractApplicationContext
    prepareRef...
Grundlegende Prinzipien
„Separation of Concerns“
      (Dijkstra, 1974)
Inversion of Control (1)
Don‘t call us, we‘ll call you!

   Hollywood-Prinzip:
   „Don‘t call us, we‘ll call you!“
       ...
Inversion of Control (2)
Verwendung in Frameworks

  Anwendungsentwickler:
      implementiert Callback-Methoden
      def...
Inversion of Control (3)
Bekannte Beispiele
  Interface ActionListener in Swing
       Zu implementieren:
       Methode v...
Inversion of Control (4)
Typische Einsatzgebiete

  Benutzeroberflächen
  Netzwerkdienste
  Systemdienste, die System- bzw...
Inversion of Control (5)
Konzeptuelle Unterscheidung
  Dependency Lookup (aktiv)
      Komponente akquiriert aktiv Referen...
Inversion of Control (5)
Elementare Begrifflichkeiten

  Komponente = Objekt bzw. Teil einer Software,
  dessen Ressourcen...
Dependency Lookup (1)
Dependency Pull

  Bekannteste Form von IoC
  Lese Abhängigkeiten von einer (zentralen) Registry



...
Dependency Lookup (2)
   Dependency Pull am Beispiel von OSGi
    public void start(BundleContext context) {
             ...
Dependency Lookup (3)
Contextualized Dependency Lookup (CDL)

    Keine zentrale Registry
    Lookup geschieht mittels ein...
Dependency Lookup (4)
Contextualized Dependency Lookup (CDL)

    Abhängigkeit ändert sich im Container
    Container ruft...
Dependency Lookup (5)
CDL = Interface Injection = Type 1 IoC

  Alternative Bezeichungen für CDL
        Interface Injecti...
Dependency Injection (1)
Setter Injection (= Type 2 IoC)

    Abhängigkeiten werden über Setter injiziert
    Komponente d...
Dependency Injection (2)
Constructor Injection (= Type 3 IoC)

    Abhängigkeiten werden über Konstruktor injiziert
    Ko...
Funktionsweise eines DI-Frameworks am Beispiel
Arbeitsweise des Frameworks
Beispiel: ein Reportgenerator
  Aufgabe: erzeuge Reports in HTML oder PDF
  Separiere Schnitts...
Reportgenerator (1)
Problem: Abhängig von Implementierung

    Problem: Klasse ReportService besitzt interne Abhängigkeit ...
Reportgenerator (2)
Schritt 1: Führe Container ein (UML)

  Entkopplung, Schritt 1: Führe Container-Klasse ein. Diese Klas...
Reportgenerator (3)
Schritt 1: Führe Container ein (cont‘d)
public class Container {
    public static Container instance;...
Reportgenerator (4)
Schritt 2: Verwende Service-Locator Pattern (UML)

  Entkopplung, Schritt 2: Verwende Service-Locator ...
Reportgenerator (5)
Schritt 2: Verwende Service-Locator Pattern (cont‘d)
public class ServiceLocator {
    private static ...
Reportgenerator (6)
Schritt 3: Realisiere DI via Reflection (UML)

  Entkopplung, Schritt 3: Verwende Konfigurationsdatei ...
Reportgenerator (7)
Schritt 3: Realisiere DI via Reflection (cont‘d)
public class Container { // Ausschnitt!
    private v...
Reportgenerator (8)
Schritt 3: Realisiere DI via Reflection (cont‘d)

   Konfigurationsdatei: configuration.properties
   ...
Reportgenerator (9)
Schritt 4: Konfiguration mit Spring Beans (UML)

  Entkopplung, Schritt 4: Verwende Spring Beans


   ...
Reportgenerator (10)
Schritt 4: Konfiguration mit Spring Beans (cont‘d)
import org.springframework.context.ApplicationCont...
Reportgenerator (10)
Schritt 4: Konfiguration mit Spring Beans (cont‘d)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmln...
Beans & ihre Konfiguration in Spring
Begrifflichkeiten Spring und J2EE
POJO vs. JavaBean vs. (Spring) Bean

  POJO (= Plain Old Java Object). Ein POJO ist ein ...
Komponenten in Spring
Spring Beans

   Bean == POJO mit eindeutiger ID
   Unterscheidung zweier Typen anhand des scope
  (...
Bean Definition (1)
Bekanntmachen von Komponenten

  Eine Bean Definition macht Spring Komponenten bekannt
  Schlüsseleige...
Bean Definition (2)
Beispiel einer XML-Konfiguration
<bean id="exampleBean" class="org.example.ExampleBean">
  <property n...
Bean-Definition (3)
Zum Beispiel gehörige Klassendefinition
public class ExampleBean {
  private AnotherBean beanOne;
  pr...
Konfiguration des Spring IoC-Containers
BeanFactory vs. Application Context

  Konfiguration des IoC-Containers via
      ...
Initialisierung des Spring IoC-Containers
Lokalisieren, Erzeugen und Verwalten von Beans

  Spring verwendet eine BeanFact...
Erzeugung von Beans (1)
Ablauf

  Ausgehend von Definitionen legt Spring Abhängigkeits-Digraphen an
  Topologische Sortier...
Erzeugung von Beans (2)
Zeitpunkt der Initialisierung
   Scope singleton – werden bei Start des Containers angelegt
   Laz...
Injizierung von Beans
Ablauf

  Ausgangslage ist wieder der Abhängigkeitsgraph
  Beans werden durch Konstructoren oder Nut...
Setzen von Bean-Attributen
Bean Properties
  Häufigste Methode von DI: Injizierung via Properties
  Injiziert werden kann ...
JavaBean Antipattern
Überprüfen von gesetzten Attributen via Spring
  Beim Arbeiten mit JavaBeans wird ein „leeres“ Objekt...
Lifecycle-Management von Beans
via Interface
   Implementiere InitializingBean oder OtherBean:
public class LifeCycle impl...
Lifecycle-Management von Beans
via Konfiguration oder Annotation
  Konfiguration:
  <bean id="lifeCycleBean"
    class="de...
Zusammenfassung & Ressourcen
Spring Core (DI)
Alternativen
  GoogleGuice: http://code.google.com/p/google-guice/
       unterstützt DI via Annotations
...
Spring Framework
Pros and Cons

  Für Dependency Injection andere starke Frameworks verfügbar
  Spring bietet viele Module...
Literatur
Webressourcen & Artikel
[Tarr et al. 1999]
    Peri Tarr, Harold Ossher, William Harrison, and Stanley M. Sutton...
Literatur
Bücher zum Thema

[Gamma et al. 1994]
   Erich Gamma et al. (Gang of Four)
   Design Patterns
   Addison Wesley,...
Vielen Dank.
Upcoming SlideShare
Loading in...5
×

Tech Talk Spring Framework

46,079

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
46,079
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
61
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Tech Talk Spring Framework"

  1. 1. Spring Framework Jens Rühmkorf Tech Talk, DLR Köln-Porz, 17. März 2009
  2. 2. Inhalt Überblick und Einführung Grundlegende Prinzipien Funktionsweise eines DI-Frameworks am Beispiel Beans & ihre Konfiguration in Spring Folie 2 Spring Framework > J. Rühmkorf > 17. März 2009
  3. 3. Überblick und Einführung
  4. 4. Spring Framework Geschichte Begonnen 2002/2003 von Rod Johnson und Jürgen Höller Spring 1.0: März 2004 Spring 1.2.6: Jolt Productivity Award 2006 (Dr. Dobb‘s Journal) Spring 2.5: November 2007, aktuell 2.5.6 Grundlagen und Prinzipien erschienen in Rod Johnsons Buch „Expert One-on-One J2EE Design and Development“ Auslöser für die Entwicklung: Hohe Komplexität von Enterprise JavaBeans (EJB bis v2.0) Folie 4 Spring Framework > J. Rühmkorf > 17. März 2009
  5. 5. Spring Framework Anforderungen an die Systemumgebung Spring 2.5 läuft auf JavaSE 6 und JavaEE 5 Für bestimmte Konfigurationsmechanismen JavaSE 5 nötig (alles alternativ auch ohne JavaSE 5 konfigurierbar) Abwärtskompatibel zu Java 1.4 bzw. Java EE 1.3 Spring-IDE 2.1 unterstützt Eclipse 3.4 (Ganymede) Folie 5 Spring Framework > J. Rühmkorf > 17. März 2009
  6. 6. Übersicht des Spring Frameworks http://static.springframework.org/spring/docs/2.5.x/reference/ Folie 6 Spring Framework > J. Rühmkorf > 17. März 2009
  7. 7. Spring Hello (1) class HelloWorld Hello World! - HelloW orld message: String Main + main(String[]) : void + hello() : void public class HelloWorld { + setMessage(String) : void private String message; public void setMessage(String message) { this.message = message; } public void hello() { System.out.println("Hello! " + message); } } Folie 7 Spring Framework > J. Rühmkorf > 17. März 2009
  8. 8. Spring Hello (2) Main import org.springframework.context.ApplicationContext; import org.springframework.context.support. ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld"); helloWorld.hello(); } } Folie 8 Spring Framework > J. Rühmkorf > 17. März 2009
  9. 9. Spring Hello (3) The Glue <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="[...]" xmlns:schemaLocation="[...]"> <bean id="helloWorld" class="de.dlr.spring101.hello.HelloWorld"> <property name="message" value="TechTalk Time!"/> </bean> </beans> Folie 9 Spring Framework > J. Rühmkorf > 17. März 2009
  10. 10. Spring Hello (4) Ausgabe 17.03.2009 15:06:45 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ab50cd: display name [org.springframework.context.support.ClassPathXmlApplicationContext@ab50cd]; startup date [Tue Mar 17 15:06:45 CET 2009]; root of context hierarchy 17.03.2009 15:06:45 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [beans.xml] 17.03.2009 15:06:46 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@ab50cd]: org.springframework.beans.factory.support.DefaultListableBeanFactory@2ce908 17.03.2009 15:06:46 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2ce908: defining beans [helloWorld]; root of factory hierarchy Hello! TechTalk Time! Folie 10 Spring Framework > J. Rühmkorf > 17. März 2009
  11. 11. Grundlegende Prinzipien
  12. 12. „Separation of Concerns“ (Dijkstra, 1974)
  13. 13. Inversion of Control (1) Don‘t call us, we‘ll call you! Hollywood-Prinzip: „Don‘t call us, we‘ll call you!“ (R.E. Sweet, SIGPLAN Notices, 1985) IoC-Ansatz ist typisch für Frameworks: „Frameworks […] emphasize design reuse over code reuse [… leading to] an inversion of control between the application and the software on which it‘s based.“ „When you use a toolkit […] you call the […] code you want to reuse.“ „When you use a framework, you […] write the code it calls.“ (Gang of Four, Design Patterns, 1994) Folie 13 Spring Framework > J. Rühmkorf > 17. März 2009
  14. 14. Inversion of Control (2) Verwendung in Frameworks Anwendungsentwickler: implementiert Callback-Methoden definiert was zu tun ist Framework: übernimmt die Verantwortung steuert zeitliche Abfolge definiert wann etwas zu tun ist Folie 14 Spring Framework > J. Rühmkorf > 17. März 2009
  15. 15. Inversion of Control (3) Bekannte Beispiele Interface ActionListener in Swing Zu implementieren: Methode void actionPerformed(ActionEvent e) Die Java-Runtime ruft die Methode auf bei Eintreten von Event Interface Runnable bei Threads Zu implementieren: Methode public void run() Java-Runtime entscheidet, wann run() aufgerufen wird Folie 15 Spring Framework > J. Rühmkorf > 17. März 2009
  16. 16. Inversion of Control (4) Typische Einsatzgebiete Benutzeroberflächen Netzwerkdienste Systemdienste, die System- bzw. Hardwareereignisse überwachen Folie 16 Spring Framework > J. Rühmkorf > 17. März 2009
  17. 17. Inversion of Control (5) Konzeptuelle Unterscheidung Dependency Lookup (aktiv) Komponente akquiriert aktiv Referenz „Dependency“ wird durch Lookup-Mechanismus nachgeschlagen Dependency Injection (passiv) Komponente stellt Methoden zur Injektion bereit Der IoC-Container injiziert die „Dependency“ buchstäblich kurz: DI Bemerkung Fowler benutzt DI synonym zu IoC http://www.martinfowler.com/articles/injection.html Hier wird DI als Spezialfall von IoC aufgefasst, vgl. http://www.picocontainer.org/inversion-of-control-history.html Folie 17 Spring Framework > J. Rühmkorf > 17. März 2009
  18. 18. Inversion of Control (5) Elementare Begrifflichkeiten Komponente = Objekt bzw. Teil einer Software, dessen Ressourcen verwaltet wird von einem: Container = Teil einer Software, der Komponenten überwacht Folie 18 Spring Framework > J. Rühmkorf > 17. März 2009
  19. 19. Dependency Lookup (1) Dependency Pull Bekannteste Form von IoC Lese Abhängigkeiten von einer (zentralen) Registry Folie 19 Spring Framework > J. Rühmkorf > 17. März 2009
  20. 20. Dependency Lookup (2) Dependency Pull am Beispiel von OSGi public void start(BundleContext context) { zur Kommunikation mit this.context = context; zentraler „Service Registry“ } public String getCustomerName(long id) { ServiceReference ref = context.getServiceReference( ILookupService.class.getName()); if(ref != null) { ILookupService lookup = (ILookupService) schlage context.getService(ref); Service nach if(lookup != null) { verwende Customer customer = lookup.findById(id); Service context.ungetService(ref); return customer.getName(); } } return null; } Folie 20 Spring Framework > J. Rühmkorf > 17. März 2009
  21. 21. Dependency Lookup (3) Contextualized Dependency Lookup (CDL) Keine zentrale Registry Lookup geschieht mittels eines Containers Container „enthält“ die Ressource / Abhängigkeit Jede interessierte Komponente implementiert ein Interface public interface ManagedComponent { public void performLookup(Container container); } Folie 21 Spring Framework > J. Rühmkorf > 17. März 2009
  22. 22. Dependency Lookup (4) Contextualized Dependency Lookup (CDL) Abhängigkeit ändert sich im Container Container ruft component.performLookup(this) auf Komponente liest und verarbeitet Abhängigkeit selbst public class ContextualizedDependencyLookup implements ManagedComponent { Aufruf durch private Dependency dep; Container public void performLookup(Container container) { this.dep = (Dependency) container.getDependency("myDependency"); } } Folie 22 Spring Framework > J. Rühmkorf > 17. März 2009
  23. 23. Dependency Lookup (5) CDL = Interface Injection = Type 1 IoC Alternative Bezeichungen für CDL Interface Injection Type 1 IoC CDL hat Nachteile Jede Komponente muss ein Interface implementieren Das Interface wird vom Container festgelegt Verwendung der Komponente in anderem Kontext nicht möglich Diese Art der Injizierung wird „intrusive“ genannt (intrusive meint hier eindringend, stark eingreifend) Folie 23 Spring Framework > J. Rühmkorf > 17. März 2009
  24. 24. Dependency Injection (1) Setter Injection (= Type 2 IoC) Abhängigkeiten werden über Setter injiziert Komponente definiert set-Methoden mit Abhängigkeiten als Parameter public class SetterInjection { private Dependency dep; public void setMyDependency(Dependency dep) { this.dep = dep; } } Folie 24 Spring Framework > J. Rühmkorf > 17. März 2009
  25. 25. Dependency Injection (2) Constructor Injection (= Type 3 IoC) Abhängigkeiten werden über Konstruktor injiziert Komponente definiert Konstruktor(en) mit Abhängigkeiten als Parameter public class ConstructorInjection { private Dependency dep; public ConstructorInjection(Dependency dep) { this.dep = dep; } } Folie 25 Spring Framework > J. Rühmkorf > 17. März 2009
  26. 26. Funktionsweise eines DI-Frameworks am Beispiel
  27. 27. Arbeitsweise des Frameworks Beispiel: ein Reportgenerator Aufgabe: erzeuge Reports in HTML oder PDF Separiere Schnittstelle und Implementierung über ein Interface Dienst wird über einen ReportService bereitgestellt class Übersicht «interface» ReportServ ice ReportGenerator + generate(String[][]) : void + generateAnnualReport(int) : void + generateDailyReport(int, int, int) : void + generateMonthlyReport(int, int) : void HtmlReportGenerator PdfReportGenerator + generate(String[][]) : void + generate(String[][]) : void Folie 27 Spring Framework > J. Rühmkorf > 17. März 2009
  28. 28. Reportgenerator (1) Problem: Abhängig von Implementierung Problem: Klasse ReportService besitzt interne Abhängigkeit auf Implementierungsklassen (HTML, PDF) public class ReportService { private ReportGenerator reportGenerator = new PdfReportGenerator(); public void generateAnnualReport(int year) { String[][] statistics = null; // Erzeuge Statistiken fuer das Jahr reportGenerator.generate(statistics); } // Rest weggelassen } Folie 28 Spring Framework > J. Rühmkorf > 17. März 2009
  29. 29. Reportgenerator (2) Schritt 1: Führe Container ein (UML) Entkopplung, Schritt 1: Führe Container-Klasse ein. Diese Klasse hat (Quelltext-)Abhängigkeiten auf alle Komponenten, die sie überwacht class Introduce Container Containe r + getComponent(String) : Object «interface» ReportServ ice ReportGenerator + generate(String[][]) : void + generateAnnualReport(int) : void + generateDailyReport(int, int, int) : void + generateMonthlyReport(int, int) : void HtmlReportGenerator PdfReportGenerator + generate(String[][]) : void + generate(String[][]) : void Folie 29 Spring Framework > J. Rühmkorf > 17. März 2009
  30. 30. Reportgenerator (3) Schritt 1: Führe Container ein (cont‘d) public class Container { public static Container instance; private Map<String, Object> components; public Container() { components = new HashMap<String, Object>(); instance = this; components.put("reportGenerator", new PdfReportGenerator()); components.put("reportService", new ReportService()); } public Object getComponent(String id) { return components.get(id); } } Folie 30 Spring Framework > J. Rühmkorf > 17. März 2009
  31. 31. Reportgenerator (4) Schritt 2: Verwende Service-Locator Pattern (UML) Entkopplung, Schritt 2: Verwende Service-Locator Pattern. Liegt OSGi zugrunde, Bestandteil von Suns Core J2EE Pattern Catalog. class Serv iceLocator Pattern Containe r Serv iceLocator + Container() + getReportGenerator() : ReportGenerat or + getComponent(String) : Object «interface» ReportServ ice ReportGenerator + generate(String[][]) : void + generateAnnualReport(int) : void + generateDailyReport(int, int, int) : void + generateMonthlyReport(int, int) : void HtmlReportGenerator PdfReportGenerator + generate(String[][]) : void + generate(String[][]) : void Folie 31 Spring Framework > J. Rühmkorf > 17. März 2009
  32. 32. Reportgenerator (5) Schritt 2: Verwende Service-Locator Pattern (cont‘d) public class ServiceLocator { private static Container container = Container.instance; public static ReportGenerator getReportGenerator() { return (ReportGenerator) container.getComponent("reportGenerator"); } } public class ReportService { private ReportGenerator reportGenerator = ServiceLocator.getReportGenerator(); // Rest weggelassen } Folie 32 Spring Framework > J. Rühmkorf > 17. März 2009
  33. 33. Reportgenerator (6) Schritt 3: Realisiere DI via Reflection (UML) Entkopplung, Schritt 3: Verwende Konfigurationsdatei um Abhängigkeiten von außen zu definieren. Instanziiere JavaBeans via Reflection. class DI v ia Reflection Containe r + Container() + getComponent(String) : Object - processEntry(String, String) : void «interface» ReportServ ice ReportGenerator + generate(String[][]) : void + generateAnnualReport(int) : void + generateDailyReport(int, int, int) : void + generateMonthlyReport(int, int) : void HtmlReportGenerator PdfReportGenerator + generate(String[][]) : void + generate(String[][]) : void Folie 33 Spring Framework > J. Rühmkorf > 17. März 2009
  34. 34. Reportgenerator (7) Schritt 3: Realisiere DI via Reflection (cont‘d) public class Container { // Ausschnitt! private void processEntry(String key, String value) throws Exception { String[] parts = key.split("."); if (parts.length == 1) { // erzeuge Komponente Object component = Class.forName(value).newInstance(); components.put(parts[0], component); } else { // injiziere Dependency Object component = components.get(parts[0]); Object reference = components.get(value); PropertyUtils.setProperty(component, parts[1], reference); } } } Folie 34 Spring Framework > J. Rühmkorf > 17. März 2009
  35. 35. Reportgenerator (8) Schritt 3: Realisiere DI via Reflection (cont‘d) Konfigurationsdatei: configuration.properties Verwendet BeanUtils aus Apache Commons # Definiere neue Komponente "reportGenerator" reportGenerator=de.dlr.spring101.report.step03. HtmlReportGenerator # Definiere neue Komponente "reportService" reportService=de.dlr.spring101.report.step03.ReportService # Injiziere die Komponente "reportGenerator" # in das Attribut "reportGenerator" reportService.reportGenerator=reportGenerator Folie 35 Spring Framework > J. Rühmkorf > 17. März 2009
  36. 36. Reportgenerator (9) Schritt 4: Konfiguration mit Spring Beans (UML) Entkopplung, Schritt 4: Verwende Spring Beans class DI thru Spring «interface» ReportServ ice ReportGenerator + generate(String[][]) : void + generateAnnualReport(int) : void + generateDailyReport(int, int, int) : void + generateMonthlyReport(int, int) : void HtmlReportGenerator PdfReportGenerator + generate(String[][]) : void + generate(String[][]) : void Folie 36 Spring Framework > J. Rühmkorf > 17. März 2009
  37. 37. Reportgenerator (10) Schritt 4: Konfiguration mit Spring Beans (cont‘d) import org.springframework.context.ApplicationContext; import org.springframework.context.support. ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); ReportService reportService = (ReportService) context.getBean("reportService"); reportService.generateAnnualReport(2008); } } Folie 37 Spring Framework > J. Rühmkorf > 17. März 2009
  38. 38. Reportgenerator (10) Schritt 4: Konfiguration mit Spring Beans (cont‘d) <?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.xsd"> <bean id="defaultGenerator" class="de.dlr.spring101.report.step04.PdfReportGenerator"/> <bean id="reportService" class="de.dlr.spring101.report.step04.ReportService"> <property name="reportGenerator"> <ref local="defaultGenerator"/> </property> </bean> </beans> Folie 38 Spring Framework > J. Rühmkorf > 17. März 2009
  39. 39. Beans & ihre Konfiguration in Spring
  40. 40. Begrifflichkeiten Spring und J2EE POJO vs. JavaBean vs. (Spring) Bean POJO (= Plain Old Java Object). Ein POJO ist ein „simples“ Java Objekt, das: 1. Keine vorgegebenen Klassen erweitert, 2. keine vorgegebenen Interfaces implementiert, 3. keine vorgegebenen Annotations enthält. JavaBean (J2EE Kontext): Ein JavaBean ist ein POJO das: 1. Öffentlichen Standardkonstruktor besitzt, 2. serialisierbar ist, 3. öffentliche Getter/Setter-Methoden besitzt. Spring Beans: Komponenten heißen in Spring Beans. Beans == POJOs. Folie 40 Spring Framework > J. Rühmkorf > 17. März 2009
  41. 41. Komponenten in Spring Spring Beans Bean == POJO mit eindeutiger ID Unterscheidung zweier Typen anhand des scope (= Gültigkeitsbereich) singleton Eine Instanz wird angelegt & referenziert bei jedem Zugriff prototype (nicht-singleton) neue Bean wird jedes Mal erzeugt analog zu new KlassenName() Weiter Typen bei Web- und Portal-Applikationen (ab Spring 2.x): request, session, globalSession Spring legt Beans i.d.R. so spät wie möglich an Folie 41 Spring Framework > J. Rühmkorf > 17. März 2009
  42. 42. Bean Definition (1) Bekanntmachen von Komponenten Eine Bean Definition macht Spring Komponenten bekannt Schlüsseleigenschaften: class (required): Java Klassenname (fully qualified, d.h. mit Package) id: eindeutiger Bezeichner für dieses Bean Konfigurationsparameter (scope, init-method etc.) constructor-arg: An den Konstruktor zu übergebende Argumente property: An die Setter bei Erzeugung (durch Spring) zu übergebende Argumente Referenzen: andere (durch Spring verwaltete) Beans können in Konstruktor oder Setter-Methode referenziert werden Bean typischerweise in einer XML-Datei definiert Folie 42 Spring Framework > J. Rühmkorf > 17. März 2009
  43. 43. Bean Definition (2) Beispiel einer XML-Konfiguration <bean id="exampleBean" class="org.example.ExampleBean"> <property name="beanOne"> <ref bean="anotherBean" /> </property> <property name="beanTwo"> <ref bean="yetAnotherBean" /> </property> <property name="integerProperty"> <value>1</value> </property> </bean> Folie 43 Spring Framework > J. Rühmkorf > 17. März 2009
  44. 44. Bean-Definition (3) Zum Beispiel gehörige Klassendefinition public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public void setBeanOne(AnotherBean beanOne) { this.beanOne = beanOne; } public void setBeanTwo(YetAnotherBean beanTwo) { this.beanTwo = beanTwo; } public void setIntegerProperty(int i) { this.i = i; } } Folie 44 Spring Framework > J. Rühmkorf > 17. März 2009
  45. 45. Konfiguration des Spring IoC-Containers BeanFactory vs. Application Context Konfiguration des IoC-Containers via XML Property-Dateien Direkter Zugriff auf die Spring-API BeanFactory und ApplicationContext sind zwei abstrakte Interfaces ApplicationContext erweitert BeanFactory (und weitere Interfaces) Ist für die meisten Anwendungsfälle zu bevorzugen Folie 45 Spring Framework > J. Rühmkorf > 17. März 2009
  46. 46. Initialisierung des Spring IoC-Containers Lokalisieren, Erzeugen und Verwalten von Beans Spring verwendet eine BeanFactory (!= FactoryBean) um Beans zu lokalisieren, zu erzeugen und zu verwalten Typischerweise verwendet man eine XML-BeanFactory: ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Folie 46 Spring Framework > J. Rühmkorf > 17. März 2009
  47. 47. Erzeugung von Beans (1) Ablauf Ausgehend von Definitionen legt Spring Abhängigkeits-Digraphen an Topologische Sortierung des Graphen (falls kreisfrei) bestimmt Reihenfolge Typischerweise werden Beans erzeugt bei Laden der Definition Ändere dies durch Attribut lazy-init: <bean class="className" lazy-init="true"/> Graph darf Kreise enthalten, ABER: Initialisierungsreihenfolge dann abhängig von der Auflösung der Kreise, nicht mehr transparent für den Nutzer Auch zirkuläre Referenzen möglich, sofern die Beans per Constructor und nicht durch eigene Factories initialisert werden (sog. FactoryBean) Vgl. http://jira.springframework.org/browse/SPR-689 Folie 47 Spring Framework > J. Rühmkorf > 17. März 2009
  48. 48. Erzeugung von Beans (2) Zeitpunkt der Initialisierung Scope singleton – werden bei Start des Containers angelegt Lazy via lazy-init – initialisiere erst, wenn die abhängige Bean angelegt wird „Very lazy“ – wird erst bei Zugriff auf Bean (via Container) im Quelltext angelegt. Dazu FactoryBean: LazyBean bean = (LazyBean) context.getBean("myBean"); Folie 48 Spring Framework > J. Rühmkorf > 17. März 2009
  49. 49. Injizierung von Beans Ablauf Ausgangslage ist wieder der Abhängigkeitsgraph Beans werden durch Konstructoren oder Nutzer-spezifizierte Factory- Methoden erzeugt Abhängigkeiten, die nicht bereits durch den Konstruktor angegeben wurde, werden via Setter-Methoden injiziert Auch direktes injizieren via Annotation möglich (dann kein Setter oder Constructor notwendig) Beispiel: @Resource(name = "someOtherBean") private OtherBean otherBean; Folie 49 Spring Framework > J. Rühmkorf > 17. März 2009
  50. 50. Setzen von Bean-Attributen Bean Properties Häufigste Methode von DI: Injizierung via Properties Injiziert werden kann eine andere Bean, ein Wert (primitiver Datentyp, String), eine Collection <bean id="exampleBean" class="de.dlr.spring101.example.ExampleBean"> <property name="anotherBean"> <ref bean="someOtherBean" /> </property> </bean> Kurzschreibweise: <bean id="exampleBean" class="de.dlr.spring101.example.ExampleBean"> <property name="anotherBean" ref="someOtherBean" /> </bean> Folie 50 Spring Framework > J. Rühmkorf > 17. März 2009
  51. 51. JavaBean Antipattern Überprüfen von gesetzten Attributen via Spring Beim Arbeiten mit JavaBeans wird ein „leeres“ Objekt initialisiert, das über Setter „befüllt“ wird Zustand ist erst valide nach Aufruf aller oder mindestens einiger Setter Überprüfung per Konfiguration: none*, simple, objects, all Annotation der Setter-Methoden mit @Resource: (einschalten via <context:annotation-config/>) @Required public void setMessage(String message) { this.message = message; } @Required public void setValue(int value) { this.value = value; } Folie 51 Spring Framework > J. Rühmkorf > 17. März 2009
  52. 52. Lifecycle-Management von Beans via Interface Implementiere InitializingBean oder OtherBean: public class LifeCycle implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { openResource(); } @Override public void destroy() throws Exception { closeResource(); } } Folie 52 Spring Framework > J. Rühmkorf > 17. März 2009
  53. 53. Lifecycle-Management von Beans via Konfiguration oder Annotation Konfiguration: <bean id="lifeCycleBean" class="de.dlr.spring101.scratchbook.LifeCycle" init-method="openResource" destroy-method="closeResource"> <property name="message" value="TechTalk Time!" /> </bean> Annotation: @PreDestroy private void closeResource() { System.out.println("close resource"); } @PostConstruct private void openResource() { System.out.println("open resource"); } Folie 53 Spring Framework > J. Rühmkorf > 17. März 2009
  54. 54. Zusammenfassung & Ressourcen
  55. 55. Spring Core (DI) Alternativen GoogleGuice: http://code.google.com/p/google-guice/ unterstützt DI via Annotations viel „Autowiring“ klein & schnell keine Unterstützung von Lifecycles (dazu: GuiceyFruit) PicoContainer: http://www.picocontainer.org/ unterstützt DI von Typ 2+3 sowie unterstützt DI mittels Annotations Unterstützung von Lifecycles klein: ~260K, etabliert Weitere Frameworks: Java-Source.net http://java-source.net/open-source/containers Folie 55 Spring Framework > J. Rühmkorf > 17. März 2009
  56. 56. Spring Framework Pros and Cons Für Dependency Injection andere starke Frameworks verfügbar Spring bietet viele Module für J2EE-Kontext („Plumbing“) Neue Konfigurationskonzepte seit Spring 2.5: Annotations (Java SE 5) Autowiring: finde passende Komponenten „automagisch“ Spring-Konfiguration üblicherweise sehr explizit (autowiring möglich) Macht das Nachvollziehen (auch für nicht-Experten) einfacher Folie 56 Spring Framework > J. Rühmkorf > 17. März 2009
  57. 57. Literatur Webressourcen & Artikel [Tarr et al. 1999] Peri Tarr, Harold Ossher, William Harrison, and Stanley M. Sutton, Jr. N Degrees of Separation: Multi-dimensional Separation of Concerns Intl. Conf. on Software Engineering (ICSE-11, 1999) http://dx.doi.org/10.1145/302405.302457 [Foote, and Yoder 1997] Brian Foote, and Joseph Yoder Big Ball of Mud 4th Conf. on Patterns Languages of Programs (PLoP ’97) http://www.laputan.org/mud/ [Fowler 2004] Martin Fowler Inversion of Control Containers and the Dependency Injection Pattern martinfowler.com, Januar 2004 http://www.martinfowler.com/articles/injection.html [Weiskotten 2006] Jeremy Weiskotten Dependency Injection & Testable Objects Dr. Dobbs Journal, April 2006 http://www.ddj.com/185300375 Folie 57 Spring Framework > J. Rühmkorf > 17. März 2009
  58. 58. Literatur Bücher zum Thema [Gamma et al. 1994] Erich Gamma et al. (Gang of Four) Design Patterns Addison Wesley, November 1994 [Mak 2008] Gary Mak Spring Recipes Apress, Juni 2008 Folie 58 Spring Framework > J. Rühmkorf > 17. März 2009
  59. 59. Vielen Dank.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×