2009 03 17 Spring101
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

2009 03 17 Spring101

on

  • 1,331 views

 

Statistics

Views

Total Views
1,331
Views on SlideShare
1,330
Embed Views
1

Actions

Likes
0
Downloads
8
Comments
0

1 Embed 1

http://www.slideshare.net 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

2009 03 17 Spring101 Presentation Transcript

  • 1. Spring Framework Jens Rühmkorf Tech Talk, DLR Köln-Porz, 17. März 2009
  • 2. Inhalt
    • Überblick und Einführung
    • Grundlegende Prinzipien
    • Funktionsweise eines DI-Frameworks am Beispiel
    • Beans & ihre Konfiguration in Spring
  • 3. Überblick und Einführung
  • 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)
  • 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)
  • 6. Übersicht des Spring Frameworks http://static.springframework.org/spring/docs/2.5.x/reference/
  • 7. Spring Hello (1) Hello World!
    • public class HelloWorld {
    • private String message ;
    • public void setMessage(String message) {
    • this . message = message;
    • }
    • public void hello() {
    • System. out .println( "Hello! " + message );
    • }
    • }
  • 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();
    • }
    • }
  • 9. Spring Hello (3) The Glue
    • < beans xmlns = &quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi = &quot; [...] &quot; xmlns:schemaLocation = &quot; [...] &quot; >
    • < bean id = &quot;helloWorld&quot; class = &quot;de.dlr.spring101.hello.HelloWorld&quot; >
    • < property name = &quot;message&quot; value = &quot;TechTalk Time!&quot; />
    • </ bean >
    • </ beans >
  • 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!
  • 11. Grundlegende Prinzipien
  • 12. „ Separation of Concerns “ (Dijkstra, 1974)
  • 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)
  • 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
  • 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
  • 16. Inversion of Control (4) Typische Einsatzgebiete
    • Benutzeroberflächen
    • Netzwerkdienste
    • Systemdienste, die System- bzw. Hardwareereignisse überwachen
  • 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
  • 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
  • 19. Dependency Lookup (1) Dependency Pull
    • Bekannteste Form von IoC
    • Lese Abhängigkeiten von einer (zentralen) Registry
  • 20.
    • public void start(BundleContext context) {
    • this . context = context;
    • }
    • public String getCustomerName( long id) {
    • ServiceReference ref = context .getServiceReference(
    • ILookupService. class .getName());
    • if (ref != null ) {
    • ILookupService lookup = (ILookupService) context .getService(ref);
    • if (lookup != null ) {
    • Customer customer = lookup.findById(id);
    • context .ungetService(ref);
    • return customer.getName();
    • }
    • }
    • return null ;
    • }
    Dependency Lookup (2) Dependency Pull am Beispiel von OSGi zur Kommunikation mit zentraler „Service Registry“ verwende Service schlage Service nach
  • 21. Dependency Lookup (3) Contextualized Dependency Lookup (CDL)
    • Keine zentrale Registry
    • Lookup geschieht mittels eines Container s
    • Container „enthält“ die Ressource / Abhängigkeit
    • Jede interessierte Komponente implementiert ein Interface
    public interface ManagedComponent { public void performLookup(Container container); }
  • 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 { private Dependency dep ; public void performLookup(Container container) { this . dep = (Dependency) container.getDependency( &quot;myDependency&quot; ); } } Aufruf durch Container
  • 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)
  • 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; } }
  • 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; } }
  • 26. Funktionsweise eines DI-Frameworks am Beispiel
  • 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
  • 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 }
  • 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
  • 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( &quot;reportGenerator&quot; , new PdfReportGenerator()); components .put( &quot;reportService&quot; , new ReportService()); } public Object getComponent(String id) { return components .get(id); } }
  • 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.
  • 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( &quot;reportGenerator&quot; ); } } public class ReportService { private ReportGenerator reportGenerator = ServiceLocator. getReportGenerator (); // Rest weggelassen }
  • 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.
  • 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( &quot;&quot; ); 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); } } }
  • 35. Reportgenerator (8) Schritt 3: Realisiere DI via Reflection (cont‘d)
    • Konfigurationsdatei: configuration.properties
    • Verwendet BeanUtils aus Apache Commons
    # Definiere neue Komponente &quot; reportGenerator &quot; reportGenerator= de.dlr.spring101.report.step03. HtmlReportGenerator # Definiere neue Komponente &quot; reportService &quot; reportService= de.dlr.spring101.report.step03.ReportService # Injiziere die Komponente &quot; reportGenerator &quot; # in das Attribut &quot; reportGenerator &quot; reportService.reportGenerator= reportGenerator
  • 36. Reportgenerator (9) Schritt 4: Konfiguration mit Spring Beans (UML)
    • Entkopplung, Schritt 4: Verwende Spring Beans
  • 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( &quot;beans.xml&quot; ); ReportService reportService = (ReportService) context.getBean( &quot;reportService&quot; ); reportService.generateAnnualReport(2008); } }
  • 38. Reportgenerator (10) Schritt 4: Konfiguration mit Spring Beans (cont‘d) <? xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> < beans xmlns = &quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi = &quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation = &quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot; > < bean id = &quot;defaultGenerator&quot; class = &quot;de.dlr.spring101.report.step04.PdfReportGenerator&quot; /> < bean id = &quot;reportService&quot; class = &quot;de.dlr.spring101.report.step04.ReportService&quot; > < property name = &quot;reportGenerator&quot; > < ref local = &quot;defaultGenerator&quot; /> </ property > </ bean > </ beans >
  • 39. Beans & ihre Konfiguration in Spring
  • 40. Begrifflichkeiten Spring und J2EE POJO vs. JavaBean vs. (Spring) Bean
    • POJO (= Plain Old Java Object). Ein POJO ist ein „simples“ Java Objekt, das:
      • Keine vorgegebenen Klassen erweitert,
      • keine vorgegebenen Interfaces implementiert,
      • keine vorgegebenen Annotations enthält.
    • JavaBean (J2EE Kontext): Ein JavaBean ist ein POJO das:
      • Öffentlichen Standardkonstruktor besitzt,
      • serialisierbar ist,
      • öffentliche Getter/Setter-Methoden besitzt.
    • Spring Beans:
      • Komponenten heißen in Spring Beans.
      • Beans == POJOs.
  • 41.
    • 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
    Komponenten in Spring Spring Beans
  • 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
  • 43.
    • < bean id = &quot;exampleBean&quot; class = &quot;org.example.ExampleBean&quot; >
    • < property name = &quot;beanOne&quot; >
    • < ref bean = &quot;anotherBean&quot; />
    • </ property >
    • < property name = &quot;beanTwo&quot; >
    • < ref bean = &quot;yetAnotherBean&quot; />
    • </ property >
    • < property name = &quot;integerProperty&quot; >
    • < value > 1 </ value >
    • </ property >
    • </ bean >
    Bean Definition (2) Beispiel einer XML-Konfiguration
  • 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;
    • }
    • }
  • 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
  • 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( &quot;beans.xml&quot; );
  • 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 = &quot;className&quot; lazy-init = &quot;true&quot; />
    • 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
  • 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( &quot;myBean&quot; );
  • 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 = &quot;someOtherBean&quot; )
    • private OtherBean otherBean ;
  • 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 = &quot;exampleBean&quot; class = &quot;de.dlr.spring101.example.ExampleBean&quot; >
    • < property name = &quot;anotherBean&quot; >
    • < ref bean = &quot;someOtherBean&quot; />
    • </ property >
    • </ bean >
    • Kurzschreibweise:
    • < bean id = &quot;exampleBean&quot; class = &quot;de.dlr.spring101.example.ExampleBean&quot; >
    • < property name = &quot;anotherBean&quot; ref = &quot;someOtherBean&quot; />
    • </ bean >
  • 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;
    • }
  • 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();
    • }
    • }
  • 53. Lifecycle-Management von Beans via Konfiguration oder Annotation
    • Konfiguration:
    • < bean id = &quot;lifeCycleBean&quot; class = &quot;de.dlr.spring101.scratchbook.LifeCycle&quot; init-method = &quot;openResource&quot; destroy-method = &quot;closeResource&quot; >
    • < property name = &quot;message&quot; value = &quot;TechTalk Time!&quot; />
    • </ bean >
    • Annotation:
    • @PreDestroy
    • private void closeResource() {
    • System. out .println( &quot;close resource&quot; );
    • }
    • @PostConstruct
    • private void openResource() {
    • System. out .println( &quot;open resource&quot; );
    • }
  • 54. Zusammenfassung & Ressourcen
  • 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
  • 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
  • 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
  • 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
  • 59. Vielen Dank.