Ik ben zelf nu al een 3 kwart jaar bezig met Spring en naarmate ik er meer van afweet en langer mee werk, naarmate ik er gekker op wordt. Voor de mensen die niet weten wat Spring is:
Spring is een platform van componenten die het gebruik van J2EE een stuk eenvoudiger maken. Een van de mission statements is dat Spring geen api`s na gaat maken als daar al goeie alternatieven voor zijn. Dus Spring is bv geen OR mapper zoals Hibernate.
Maar wat is Spring dan wel? Dat vond ik in het begin eigelijk vrij onduidelijk.. waar ligt de grens tusse Spring en andere tools?. De basis van Spring is een Inversion of Control container. Dit is een container waarin je normale Java objecten (Pojo`s : Plain Old Java Objects) kunt aanmaken. In deze container lijm je de grote bouwstenen van je systeem in elkaar en configureer je ze met de juiste argumenten. Deze container is dus een soortement van vergaarbak waarin al je objecten worden aangemaakt, eventueel krijgen ze de mogelijkheid om nog wat initialisatie functionaliteit uit te voeren. Maar ze krijgen ook de mogelijkheid om zaken af te sluiten op het moment dat de container af gaat sluiten. Op alle objecten in die container wordt dus een stuk live cycle management uitgeoefend en krijg je op een hele nette manier de kans om goed op te starten en af te sluiten. Verder is het nu ook eenvoudig om aan referenties naar andere objecten te komen (ook altijd een groot gemis in J2EE). Geen zielig gestuntel met JNDI meer.. maar gewoon zoals het altijd al had gemoeten.
Maar wat is dan nu dat IOC gedeelte? In principe is het vrij eenvoudig. Je geeft een object niet meer de verantwoordelijk voor het aanmaken van de componenten die hij gebruikt, in plaats hiervan injecteer je de componententen (de afhankelijkheden) erin (dependency injection). 2 Van de meest gebruikte mogelijkheden om te injecteren zijn : de constructor (mijn favoriet.. ik kan de garantie geven dat mijn objecten ten alle tijden valid zijn), of via een setter.
Een voorbeeld:
Ik heb een object dat documenten moet analyzeren:
De Executor is een onderdeel van Java 5.0 en beschrijft de interface waaraan een dienst moet voldoen die runnable taken kan uitvoeren. Stel dat ik wil dat een threadpool wordt gebruikt om die taken naast elkaar uit te voeren, dan zou ik dan in Spring op de volgende manier kunnen oplossen:
Zoals je kunt zien is de documentAnalyzer nu voorzien van een ThreadPoolExecutor waarmee ik dus een pool van threads tot mijn beschikking heb die deze taken uitvoert. Maar voor het testen is het werken met een threadpool erg onplezierig omdat ik dus een extra thread in mijn systeem heb. Gelukkig kan ik aan de DocumentAnalyzer ook een volledig andere implementatie van die Executor meegeven, namelijk de DirectExecutor:
Zoals je kunt zien leg je de verantwoordelijkheid hoe objecten op worden gebouwd niet meer volledig bij het object neer. Het object beschrijft wat hij nodig heeft en zo lang jij je aan dat contract houdt, komt (meestal) alles goed. Het object is een soortement van framework achtig component waarin specifieke functionaliteit geinjecteerd kan worden.
Dit zorgt ervoor dat je objecten veel beter herbruikbaar zijn en ook veel beter te testen zijn. Mij is opgevallen dat ik nu met 2 petten op naar mijn code kijk, namelijk dat als component schrijver en component configurator.
Tot zover dit voorbeeld, maar dit is echt nog maar een puntje van de ijsberg. Spring kan echter nog veel meer: transacties toevoegen, security toevoegen, remoting toevoegen, jmx toevoegen etc etc (de lijst houd niet op). Spring is een heel framework van tools waardoor je (in mijn ogen) op een veel betere manier gaat werken. Niet langer van die lompe J2EE oplossingen, maar lichte en elegante oplossingen. Spring is zoals J2EE al lang had moeten zijn.
Dus wie is er al bezig met Spring? Wie is geinteresseerd? Wie heeft heeft het de kreet wel eens horen vallen? Wie is er al verliefd?
Spring is een platform van componenten die het gebruik van J2EE een stuk eenvoudiger maken. Een van de mission statements is dat Spring geen api`s na gaat maken als daar al goeie alternatieven voor zijn. Dus Spring is bv geen OR mapper zoals Hibernate.
Maar wat is Spring dan wel? Dat vond ik in het begin eigelijk vrij onduidelijk.. waar ligt de grens tusse Spring en andere tools?. De basis van Spring is een Inversion of Control container. Dit is een container waarin je normale Java objecten (Pojo`s : Plain Old Java Objects) kunt aanmaken. In deze container lijm je de grote bouwstenen van je systeem in elkaar en configureer je ze met de juiste argumenten. Deze container is dus een soortement van vergaarbak waarin al je objecten worden aangemaakt, eventueel krijgen ze de mogelijkheid om nog wat initialisatie functionaliteit uit te voeren. Maar ze krijgen ook de mogelijkheid om zaken af te sluiten op het moment dat de container af gaat sluiten. Op alle objecten in die container wordt dus een stuk live cycle management uitgeoefend en krijg je op een hele nette manier de kans om goed op te starten en af te sluiten. Verder is het nu ook eenvoudig om aan referenties naar andere objecten te komen (ook altijd een groot gemis in J2EE). Geen zielig gestuntel met JNDI meer.. maar gewoon zoals het altijd al had gemoeten.
Maar wat is dan nu dat IOC gedeelte? In principe is het vrij eenvoudig. Je geeft een object niet meer de verantwoordelijk voor het aanmaken van de componenten die hij gebruikt, in plaats hiervan injecteer je de componententen (de afhankelijkheden) erin (dependency injection). 2 Van de meest gebruikte mogelijkheden om te injecteren zijn : de constructor (mijn favoriet.. ik kan de garantie geven dat mijn objecten ten alle tijden valid zijn), of via een setter.
Een voorbeeld:
Ik heb een object dat documenten moet analyzeren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class DocumentAnalyzer{
private Executor _executor;
public ExecutorService(Executor executor){
_executor = executor;
}
public void analyze(final Document document){
Runnable r = new Runnable(){
public void run(){
..doe dikke analyse dingen met het document
}
};
_executor.submit(r);
}
} |
De Executor is een onderdeel van Java 5.0 en beschrijft de interface waaraan een dienst moet voldoen die runnable taken kan uitvoeren. Stel dat ik wil dat een threadpool wordt gebruikt om die taken naast elkaar uit te voeren, dan zou ik dan in Spring op de volgende manier kunnen oplossen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| <bean id="documentAnalyzerExecutorService"
class="edu.emory.mathcs.util.concurrent.ThreadPoolExecutor"
destroy-method="shutdown">
<!-- core pool size -->
<constructor-arg index="0">
<value>5</value>
</constructor-arg>
<!-- max pool size -->
<constructor-arg index="1">
<value>10</value>
</constructor-arg>
<!-- die-time -->
<constructor-arg index="2">
<value>5000</value>
</constructor-arg>
<constructor-arg index="3">
<ref bean="edu.emory.mathcs.util.concurrent.TimeUnit.MILLISECONDS"/>
</constructor-arg>
<constructor-arg index="4">
<bean class="edu.emory.mathcs.util.concurrent.LinkedBlockingQueue"/>
</constructor-arg>
</bean>
<bean id="documentAnalyzer"
class="DocumentAnalyzer">
<constructor-arg>
<ref bean="documentAnalyzerExecutorService"/>
</constructor-arg>
</bean> |
Zoals je kunt zien is de documentAnalyzer nu voorzien van een ThreadPoolExecutor waarmee ik dus een pool van threads tot mijn beschikking heb die deze taken uitvoert. Maar voor het testen is het werken met een threadpool erg onplezierig omdat ik dus een extra thread in mijn systeem heb. Gelukkig kan ik aan de DocumentAnalyzer ook een volledig andere implementatie van die Executor meegeven, namelijk de DirectExecutor:
code:
1
2
3
4
5
| class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
} |
Zoals je kunt zien leg je de verantwoordelijkheid hoe objecten op worden gebouwd niet meer volledig bij het object neer. Het object beschrijft wat hij nodig heeft en zo lang jij je aan dat contract houdt, komt (meestal) alles goed. Het object is een soortement van framework achtig component waarin specifieke functionaliteit geinjecteerd kan worden.
Dit zorgt ervoor dat je objecten veel beter herbruikbaar zijn en ook veel beter te testen zijn. Mij is opgevallen dat ik nu met 2 petten op naar mijn code kijk, namelijk dat als component schrijver en component configurator.
Tot zover dit voorbeeld, maar dit is echt nog maar een puntje van de ijsberg. Spring kan echter nog veel meer: transacties toevoegen, security toevoegen, remoting toevoegen, jmx toevoegen etc etc (de lijst houd niet op). Spring is een heel framework van tools waardoor je (in mijn ogen) op een veel betere manier gaat werken. Niet langer van die lompe J2EE oplossingen, maar lichte en elegante oplossingen. Spring is zoals J2EE al lang had moeten zijn.
Dus wie is er al bezig met Spring? Wie is geinteresseerd? Wie heeft heeft het de kreet wel eens horen vallen? Wie is er al verliefd?
[ Voor 79% gewijzigd door Alarmnummer op 23-03-2005 21:41 ]