Upload
gueste4be40
View
774
Download
0
Embed Size (px)
Citation preview
Spring Framework
Jens Rühmkorf Tech Talk, DLR Köln-Porz, 17. März 2009
Folie 2Spring Framework > J. Rühmkorf > 17. März 2009
Inhalt
Überblick und Einführung
Grundlegende Prinzipien
Funktionsweise eines DI-Frameworks am Beispiel
Beans & ihre Konfiguration in Spring
Überblick und Einführung
Folie 4Spring Framework > J. Rühmkorf > 17. März 2009
Spring FrameworkGeschichte
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 5Spring Framework > J. Rühmkorf > 17. März 2009
Spring FrameworkAnforderungen 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 6Spring Framework > J. Rühmkorf > 17. März 2009
Übersicht des Spring Frameworkshttp://static.springframework.org/spring/docs/2.5.x/reference/
Folie 7Spring Framework > J. Rühmkorf > 17. März 2009
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);
}
}
class HelloWorld
HelloW orld
- message: String
+ hello() : void+ setMessage(String) : void
Main
+ main(String[]) : void
Folie 8Spring Framework > J. Rühmkorf > 17. März 2009
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 9Spring Framework > J. Rühmkorf > 17. März 2009
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 10Spring Framework > J. Rühmkorf > 17. März 2009
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
obtainFreshBeanFactoryINFO: 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!
Grundlegende Prinzipien
„Separation of
Concerns“(Dijkstra, 1974)
Folie 13Spring Framework > J. Rühmkorf > 17. März 2009
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 14Spring Framework > J. Rühmkorf > 17. März 2009
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 15Spring Framework > J. Rühmkorf > 17. März 2009
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 16Spring Framework > J. Rühmkorf > 17. März 2009
Inversion of Control (4)Typische Einsatzgebiete
Benutzeroberflächen
Netzwerkdienste
Systemdienste, die System- bzw. Hardwareereignisse überwachen
Folie 17Spring Framework > J. Rühmkorf > 17. März 2009
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 bereitDer IoC-Container injiziert die „Dependency“ buchstäblichkurz: DI
BemerkungFowler 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 18Spring Framework > J. Rühmkorf > 17. März 2009
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 19Spring Framework > J. Rühmkorf > 17. März 2009
Dependency Lookup (1)Dependency Pull
Bekannteste Form von IoC
Lese Abhängigkeiten von einer (zentralen) Registry
Folie 20Spring Framework > J. Rühmkorf > 17. März 2009
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
Folie 21Spring Framework > J. Rühmkorf > 17. März 2009
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 22Spring Framework > J. Rühmkorf > 17. März 2009
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("myDependency");
}
}
Aufruf durch Container
Folie 23Spring Framework > J. Rühmkorf > 17. März 2009
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 24Spring Framework > J. Rühmkorf > 17. März 2009
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 25Spring Framework > J. Rühmkorf > 17. März 2009
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;
}
}
Funktionsweise eines DI-Frameworks am Beispiel
Folie 27Spring Framework > J. Rühmkorf > 17. März 2009
Arbeitsweise des FrameworksBeispiel: ein Reportgenerator
Aufgabe: erzeuge Reports in HTML oder PDF
Separiere Schnittstelle und Implementierung über ein Interface
Dienst wird über einen ReportService bereitgestellt
class Übersicht
HtmlReportGenerator
+ generate(String[][]) : void
PdfReportGenerator
+ generate(String[][]) : void
«interface»ReportGenerator
+ generate(String[][]) : void
ReportServ ice
+ generateAnnualReport(int) : void+ generateDailyReport(int, int, int) : void+ generateMonthlyReport(int, int) : void
Folie 28Spring Framework > J. Rühmkorf > 17. März 2009
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 29Spring Framework > J. Rühmkorf > 17. März 2009
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
HtmlReportGenerator
+ generate(String[][]) : void
PdfReportGenerator
+ generate(String[][]) : void
«interface»ReportGenerator
+ generate(String[][]) : void
ReportServ ice
+ generateAnnualReport(int) : void+ generateDailyReport(int, int, int) : void+ generateMonthlyReport(int, int) : void
Folie 30Spring Framework > J. Rühmkorf > 17. März 2009
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);
}
}
Reportgenerator (3)Schritt 1: Führe Container ein (cont‘d)
Folie 31Spring Framework > J. Rühmkorf > 17. März 2009
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
+ Container()+ getComponent(String) : Object
HtmlReportGenerator
+ generate(String[][]) : void
PdfReportGenerator
+ generate(String[][]) : void
«interface»ReportGenerator
+ generate(String[][]) : void
ReportServ ice
+ generateAnnualReport(int) : void+ generateDailyReport(int, int, int) : void+ generateMonthlyReport(int, int) : void
Serv iceLocator
+ getReportGenerator() : ReportGenerator
Folie 32Spring Framework > J. Rühmkorf > 17. März 2009
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
}
Reportgenerator (5)Schritt 2: Verwende Service-Locator Pattern (cont‘d)
Folie 33Spring Framework > J. Rühmkorf > 17. März 2009
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
HtmlReportGenerator
+ generate(String[][]) : void
PdfReportGenerator
+ generate(String[][]) : void
«interface»ReportGenerator
+ generate(String[][]) : void
ReportServ ice
+ generateAnnualReport(int) : void+ generateDailyReport(int, int, int) : void+ generateMonthlyReport(int, int) : void
Folie 34Spring Framework > J. Rühmkorf > 17. März 2009
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);
}
}
}
Reportgenerator (7)Schritt 3: Realisiere DI via Reflection (cont‘d)
Folie 35Spring Framework > J. Rühmkorf > 17. März 2009
# 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
Reportgenerator (8)Schritt 3: Realisiere DI via Reflection (cont‘d)
Konfigurationsdatei: configuration.properties
Verwendet BeanUtils aus Apache Commons
Folie 36Spring Framework > J. Rühmkorf > 17. März 2009
Reportgenerator (9)Schritt 4: Konfiguration mit Spring Beans (UML)
Entkopplung, Schritt 4: Verwende Spring Beans
class DI thru Spring
HtmlReportGenerator
+ generate(String[][]) : void
PdfReportGenerator
+ generate(String[][]) : void
«interface»ReportGenerator
+ generate(String[][]) : void
ReportServ ice
+ generateAnnualReport(int) : void+ generateDailyReport(int, int, int) : void+ generateMonthlyReport(int, int) : void
Folie 37Spring Framework > J. Rühmkorf > 17. März 2009
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);
}
}
Reportgenerator (10)Schritt 4: Konfiguration mit Spring Beans (cont‘d)
Folie 38Spring Framework > J. Rühmkorf > 17. März 2009
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>
Beans & ihre Konfiguration in Spring
Folie 40Spring Framework > J. Rühmkorf > 17. März 2009
Begrifflichkeiten Spring und J2EEPOJO 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 41Spring Framework > J. Rühmkorf > 17. März 2009
Bean == POJO mit eindeutiger IDUnterscheidung zweier Typen anhand des scope (= Gültigkeitsbereich)
singletonEine Instanz wird angelegt & referenziert bei jedem Zugriff
prototype (nicht-singleton)neue Bean wird jedes Mal erzeugtanalog zu new KlassenName()
Weiter Typen bei Web- und Portal-Applikationen (ab Spring 2.x):request, session, globalSessionSpring legt Beans i.d.R. so spät wie möglich an
Komponenten in SpringSpring Beans
Folie 42Spring Framework > J. Rühmkorf > 17. März 2009
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 43Spring Framework > J. Rühmkorf > 17. März 2009
<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>
Bean Definition (2)Beispiel einer XML-Konfiguration
Folie 44Spring Framework > J. Rühmkorf > 17. März 2009
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 45Spring Framework > J. Rühmkorf > 17. März 2009
Konfiguration des Spring IoC-ContainersBeanFactory 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 46Spring Framework > J. Rühmkorf > 17. März 2009
Initialisierung des Spring IoC-Containers Lokalisieren, Erzeugen und Verwalten von Beans
Spring verwendet eine BeanFactory (!= FactoryBean) um Beanszu lokalisieren, zu erzeugen und zu verwalten
Typischerweise verwendet man eine XML-BeanFactory:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Folie 47Spring Framework > J. Rühmkorf > 17. März 2009
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 48Spring Framework > J. Rühmkorf > 17. März 2009
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 49Spring Framework > J. Rühmkorf > 17. März 2009
Injizierung von BeansAblauf
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 50Spring Framework > J. Rühmkorf > 17. März 2009
Setzen von Bean-AttributenBean Properties
Häufigste Methode von DI: Injizierung via PropertiesInjiziert 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 51Spring Framework > J. Rühmkorf > 17. März 2009
JavaBean AntipatternÜberprüfen von gesetzten Attributen via Spring
Beim Arbeiten mit JavaBeans wird ein „leeres“ Objekt initialisiert, das über Setter „befüllt“ wirdZustand ist erst valide nach Aufruf aller oder mindestens einiger SetterÜberprüfung per Konfiguration:none*, simple, objects, allAnnotation der Setter-Methoden mit @Resource: (einschalten via <context:annotation-config/>)@Requiredpublic void setMessage(String message) { this.message = message;}@Requiredpublic void setValue(int value) { this.value = value;}
Folie 52Spring Framework > J. Rühmkorf > 17. März 2009
Lifecycle-Management von Beansvia 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 53Spring Framework > J. Rühmkorf > 17. März 2009
Lifecycle-Management von Beansvia 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:@PreDestroyprivate void closeResource() { System.out.println("close resource");}@PostConstructprivate void openResource() { System.out.println("open resource");}
Zusammenfassung & Ressourcen
Folie 55Spring Framework > J. Rühmkorf > 17. März 2009
Spring Core (DI)Alternativen
GoogleGuice: http://code.google.com/p/google-guice/ unterstützt DI via Annotationsviel „Autowiring“klein & schnellkeine Unterstützung von Lifecycles (dazu: GuiceyFruit)
PicoContainer: http://www.picocontainer.org/ unterstützt DI von Typ 2+3 sowie unterstützt DI mittels AnnotationsUnterstützung von Lifecyclesklein: ~260K, etabliert
Weitere Frameworks: Java-Source.nethttp://java-source.net/open-source/containers
Folie 56Spring Framework > J. Rühmkorf > 17. März 2009
Spring FrameworkPros 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 57Spring Framework > J. Rühmkorf > 17. März 2009
LiteraturWebressourcen & Artikel
[Tarr et al. 1999]Peri Tarr, Harold Ossher, William Harrison, and Stanley M. Sutton, Jr.N Degrees of Separation: Multi-dimensional Separation of ConcernsIntl. Conf. on Software Engineering (ICSE-11, 1999)http://dx.doi.org/10.1145/302405.302457
[Foote, and Yoder 1997]Brian Foote, and Joseph YoderBig Ball of Mud4th Conf. on Patterns Languages of Programs (PLoP ’97)http://www.laputan.org/mud/
[Fowler 2004] Martin FowlerInversion of Control Containers and the Dependency Injection Patternmartinfowler.com, Januar 2004http://www.martinfowler.com/articles/injection.html
[Weiskotten 2006] Jeremy WeiskottenDependency Injection & Testable ObjectsDr. Dobbs Journal, April 2006http://www.ddj.com/185300375
Folie 58Spring Framework > J. Rühmkorf > 17. März 2009
LiteraturBücher zum Thema
[Gamma et al. 1994] Erich Gamma et al. (Gang of Four)Design PatternsAddison Wesley, November 1994
[Mak 2008] Gary MakSpring RecipesApress, Juni 2008
Vielen Dank.