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
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. 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. Ü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. 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. 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. 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. 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
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. 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. 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. 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. 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. 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. 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. 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) {
Customer customer = lookup.findById(id);
verwende context.ungetService(ref);
Service
return customer.getName();
}
}
return null;
}
Folie 20
Spring Framework > J. Rühmkorf > 17. März 2009
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. 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. 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. 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. 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
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. 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. 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. 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. 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 PdfReportGenerato r
+ generate(String[][]) : void + generate(String[][]) : void
Folie 31
Spring Framework > J. Rühmkorf > 17. März 2009
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. 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. 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. 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. 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. 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. 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
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.
Folie 40
Spring Framework > J. Rühmkorf > 17. März 2009
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
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. 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. 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. 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