SlideShare une entreprise Scribd logo
1  sur  120
Télécharger pour lire hors ligne
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
warum denn CDI ? ;-)
@SvenRuppert 4/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
oft gehörte Antwort
kürzere Notation.. *oje*
Manchmal ist die Notation per Inject kürzer. Sobald allerdings die einzelnen
Qualifier dazukommen, ist meist der Aufwand zum Aufruf eines Konstruktors
kaum unterschiedlich.
Verkürzen der Notation ist natürlich nicht das Ziel von CDI
@SvenRuppert 5/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
lösen/entfernen von statischen Abhängigkeiten
@SvenRuppert 6/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
lösen/entfernen von statischen Abhängigkeiten
Dieser Punkt ist einer der wesentlichen.
Also: Wie kann man zur Entwicklungszeit die Abhängigkeiten zu den anderen
Projektmodulen möglichst gering halten?
@SvenRuppert 7/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
lösen/entfernen von statischen Abhängigkeiten
Dieser Punkt ist einer der wesentlichen.
Also: Wie kann man zur Entwicklungszeit die Abhängigkeiten zu den anderen
Projektmodulen möglichst gering halten?
Gehen wir von der Definition einer Liste aus. Als Rückgabewert einer Methode
wird eine Instanz der Implementierung von List verwendet.
publicList<Data>execute(){...}; JAVA
@SvenRuppert 8/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Damit sind nachfolgende Aufrufer nicht mehr an die Implementierung der List
gebunden.
importjava.util.List;
importjava.util.ArrayList;
publicList<Data>execute(){
finalList<Data>result=newArrayList<>();
//....
returnresult;
}
JAVA
@SvenRuppert 9/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Damit sind nachfolgende Aufrufer nicht mehr an die Implementierung der List
gebunden.
In der Methode jedoch besteht meist die Abhängigkeit zu der entsprechenden
Implementierung obwohl auch das meist nicht notwendig ist.
importjava.util.List;
importjava.util.ArrayList;
publicList<Data>execute(){
finalList<Data>result=newArrayList<>();
//....
returnresult;
}
JAVA
@SvenRuppert 10/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList
verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet.
@SvenRuppert 11/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList
verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet.
Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig.
@SvenRuppert 12/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList
verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet.
Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig.
Sollte sich zur Laufzeit herausstellen, das die Wahl dieser Implementierung nicht
optimal gewesen ist, muss der Quelltext angepasst und neu verteilt werden.
@SvenRuppert 13/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList
verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet.
Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig.
Sollte sich zur Laufzeit herausstellen, das die Wahl dieser Implementierung nicht
optimal gewesen ist, muss der Quelltext angepasst und neu verteilt werden.
z.B. Mit std SE Mitteln kann man das durch entsprechende Factories lösen.
@SvenRuppert 14/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Mit std SE Mitteln kann man das durch entsprechende Factories lösen.
Beispielhaft soll hier folgende Implementierung verwendet werden.
importjava.util.ArrayList;
importjava.util.LinkedList;
importjava.util.List;
publicclassListFactory{
publicListcreateArrayList() {returnnewArrayList();}
publicListcreateLinkedList(){returnnewLinkedList();}
publicListcreateList() {returnnewArrayList();}
}
JAVA
@SvenRuppert 15/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Haben wir damit etwas erreicht?
@SvenRuppert 16/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Haben wir damit etwas erreicht?
... bzw was haben wir damit erreicht?
@SvenRuppert 17/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Haben wir damit etwas erreicht?
... bzw was haben wir damit erreicht?
z.B. Die Entwickler verwenden nun diese Factory.
@SvenRuppert 18/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Haben wir damit etwas erreicht?
... bzw was haben wir damit erreicht?
z.B. Die Entwickler verwenden nun diese Factory. -> wenn sie wissen das es diese
gibt! ;-)
@SvenRuppert 19/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Vorher / Nachher (1/2)
importjava.util.List;
importjava.util.ArrayList;
publicList<Data>execute(){
finalList<Data>result=newArrayList<>();
//....
returnresult;
}
JAVA
@SvenRuppert 20/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Vorher / Nachher (2/2)
importjava.util.List;
importjava.util.ArrayList;
publicList<Data>execute(){
finalList<Data>result=newArrayList<>();
//....
returnresult;
}
importjava.util.List;
importorg.rapidpm.demo.ListFactory;
publicList<Data>execute(){
finalListlist=newListFactory().createArrayList();
//....
returnresult;
}
JAVA
@SvenRuppert 21/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert.
@SvenRuppert 22/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert.
Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit
gefallen.
@SvenRuppert 23/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert.
Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit
gefallen.
Die Abhängigkeit zur Factory wurde hinzugefügt.
@SvenRuppert 24/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert.
Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit
gefallen.
Die Abhängigkeit zur Factory wurde hinzugefügt.
Die Implementierung der ListFactory selber hat auch wieder die statischen
Abhängigkeiten zu allen vorgesehenen Implementierungen.
@SvenRuppert 25/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen
Implementierungen
@SvenRuppert 26/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen
Implementierungen
Anforderung Nr 2: keine statischen Entscheidungen für spezifische
Implementierungen
@SvenRuppert 27/122
Warum CDI oder
gibt es einen tieferen Sinn dahinter?
Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen
Implementierungen
Anforderung Nr 2: keine statischen Entscheidungen für spezifische
Implementierungen
Was ist jetzt eine mögliche Lösung ???
@SvenRuppert 28/122
Lösungsversuch Nr 1
basierend auf Java SE
Eine etwas dynamischere Lösung...
@SvenRuppert 29/122
Lösungsversuch Nr 1
basierend auf Java SE
Eine etwas dynamischere Lösung...
importjava.util.ArrayList;
importjava.util.LinkedList;
importjava.util.List;
importorg.rapidpm.demo.cdi.commons.registry.ContextResolver;
publicclassListFactory{
publicListcreateList(finalContextResolvercontextResolver){
if(contextResolver==null){returncreateArrayList();}
else{
if(contextResolver.resolveContext()){returncreateArrayList();}
else{returncreateLinkedList();}
}
}
}
JAVA
@SvenRuppert 30/122
Lösungsversuch Nr 1
basierend auf Java SE
Eine etwas dynamischere Lösung...
Die Komplexität der Entscheidung liegt nun im ContextResolver
@SvenRuppert 31/122
Lösungsversuch Nr 1
basierend auf Java SE
Eine etwas dynamischere Lösung...
Die Komplexität der Entscheidung liegt nun im ContextResolver
Abhängigkeit in der Factory zum ContextResolver hinzugefügt
@SvenRuppert 32/122
Lösungsversuch Nr 1
basierend auf Java SE
Eine etwas dynamischere Lösung...
Die Komplexität der Entscheidung liegt nun im ContextResolver
Abhängigkeit in der Factory zum ContextResolver hinzugefügt
Gewonnen: zur Laufzeit sich für eine Implementierung entscheiden.
@SvenRuppert 33/122
Lösungsversuch Nr 1
basierend auf Java SE
Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen
Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste
hat, muss eine z.B. Registry gebaut werden.
@SvenRuppert 34/122
Lösungsversuch Nr 1
basierend auf Java SE
Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen
Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste
hat, muss eine z.B. Registry gebaut werden.
Dort kann man zur Laufzeit die jeweiligen Implementierungen registrieren und
für eine Auflösung zur Verfügung stellen.
@SvenRuppert 35/122
Lösungsversuch Nr 1
basierend auf Java SE
Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen
Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste
hat, muss eine z.B. Registry gebaut werden.
Dort kann man zur Laufzeit die jeweiligen Implementierungen registrieren und
für eine Auflösung zur Verfügung stellen.
Hier hilft CDI durch seine Konzepte, ohne das man sich mit der
Basisimplementierung der Infrastruktur beschäftigen muss.
@SvenRuppert 36/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@SvenRuppert 37/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@InjectListlist; JAVA
@SvenRuppert 38/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@Inject@CDILegacyTestListlist; JAVA
@SvenRuppert 39/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@Inject@CDILegacyTestListlist;
@Produces@CDILegacyTest
publicListcreateList(...){...}
JAVA
@SvenRuppert 40/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@Inject@CDILegacyTestListlist;
@Produces@CDILegacyTest
publicListcreateList(InjectionPointinjectionPoint,
BeanManagerbeanManager,ContextResolvercontextResolver){
....
}
JAVA
@SvenRuppert 41/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
@Inject@CDILegacyTestListlist;
@Produces@CDILegacyTest
publicListcreateList(InjectionPointinjectionPoint,
BeanManagerbeanManager,ContextResolvercontextResolver){
booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen...
if(b){returnnewLinkedList();}else{returnnewArrayList();}
}
JAVA
@SvenRuppert 42/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen werden per @Inject durch den Container zur Verfügung gestellt
Aber leider ist das immer noch zu dem Zeitpunkt zu dem die umliegende Instanz
erzeugt wird.
@Inject@CDILegacyTestListlist;
@Produces@CDILegacyTest
publicListcreateList(InjectionPointinjectionPoint,
BeanManagerbeanManager,ContextResolvercontextResolver){
booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen...
if(b){returnnewLinkedList();}else{returnnewArrayList();}
}
JAVA
@SvenRuppert 43/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden.
@SvenRuppert 44/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden.
Damit sind späte Entscheidungen möglich
@SvenRuppert 45/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden.
Damit sind späte Entscheidungen möglich
@Inject@CDILegacyTestInstance<List>listInstance; JAVA
@SvenRuppert 46/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden.
Damit sind späte Entscheidungen möglich
@Inject@CDILegacyTestInstance<List>listInstance;
//..später
finalListlist=listInstance.get();
JAVA
@SvenRuppert 47/122
endlich CDI ;-)
basierend auf Weld / WELD-SE
Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden
damit sind späte Entscheidungen möglich
@Inject@CDILegacyTestInstance<List>listInstance;
//..später
finalListlist=listInstance.get();
@Produces@CDILegacyTest
publicListcreateList(InjectionPointinjectionPoint,
BeanManagerbeanManager,ContextResolvercontextResolver){
booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen...
if(b){returnnewLinkedList();}else{returnnewArrayList();}
}
JAVA
@SvenRuppert 48/122
CDI
was wurde bis jetzt erreicht?
Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der
Vererbung
@SvenRuppert 49/122
CDI
was wurde bis jetzt erreicht?
Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der
Vererbung
Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt
@SvenRuppert 50/122
CDI
was wurde bis jetzt erreicht?
Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der
Vererbung
Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt
Für jede Entscheidung einen Producer
@SvenRuppert 51/122
CDI
was wurde bis jetzt erreicht?
Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der
Vererbung
Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt
Für jede Entscheidung einen Producer.. wie funktioniert das praktisch?
@SvenRuppert 52/122
CDI
was wurde bis jetzt erreicht?
Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der
Vererbung
Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt
Für jede Entscheidung einen Producer.. wie funktioniert das praktisch?
... sehen wir uns gleich noch an.... Bitte ein wenig Geduld...
@SvenRuppert 53/122
CDI
was wurde dafür in Kauf genommen?
statische Kopplung über AnnotationsLiterale:
@Inject@MyQualifierListliste; JAVA
@SvenRuppert 54/122
CDI
was wurde dafür in Kauf genommen?
statische Kopplung über AnnotationsLiterale:
schlechterer Umgang mit Generics
@Inject@MyQualifierListliste; JAVA
@SvenRuppert 55/122
CDI
was wurde dafür in Kauf genommen?
statische Kopplung über AnnotationsLiterale:
schlechterer Umgang mit Generics
keine Komplexitätsreduktion für den Entwickler
@Inject@MyQualifierListliste; JAVA
@SvenRuppert 56/122
CDI explained by code
HelloLogger zum aufwärmen/wiederholen
klassischer Fall, Logger im System
@Inject@CDILoggerLoggerlogger; JAVA
@SvenRuppert 57/122
CDI explained by code
HelloLogger zum aufwärmen/wiederholen
klassischer Fall, Logger im System
@Inject@CDILoggerLoggerlogger;
@Qualifier
@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE})
public@interfaceCDILogger{}
JAVA
@SvenRuppert 58/122
CDI explained by code
HelloLogger zum aufwärmen/wiederholen
klassischer Fall, Logger im System
@Inject@CDILoggerLoggerlogger;
@Qualifier
@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE})
public@interfaceCDILogger{}
@Produces@CDILogger
publicLoggerproduceLog4JLogger(InjectionPointiP,BeanManagerbeanManager){
finalClass<?>declaringClass=iP.getMember().getDeclaringClass();
returnnewLogger(declaringClass);
}
JAVA
@SvenRuppert 59/122
CDI explained by code
HelloLogger zum aufwärmen/wiederholen
klassischer Fall, Logger im System
@Inject@CDILoggerLoggerlogger;
@Qualifier
@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE})
public@interfaceCDILogger{}
@Produces@CDILogger
publicLoggerproduceLog4JLogger(InjectionPointiP,BeanManagerbeanManager){
finalClass<?>declaringClass=iP.getMember().getDeclaringClass();
returnnewLogger(declaringClass);//Loggernichtgemanaged!!!
}
JAVA
@SvenRuppert 60/122
CDI explained by code
HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht?
Referenz auf Factory wird ersetzt durch Qualifier. :-(
@Inject@CDILoggerLoggerlogger; JAVA
@SvenRuppert 61/122
CDI explained by code
HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht?
Referenz auf Factory wird ersetzt durch Qualifier. :-(
Spezifische Producer losgelöst von den anderen Producern
@Inject@CDILoggerLoggerlogger; JAVA
@SvenRuppert 62/122
CDI explained by code
HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht?
Referenz auf Factory wird ersetzt durch Qualifier. :-(
Spezifische Producer losgelöst von den anderen Producern
zentrale Stelle für context-bezogene Entscheidungen
@Inject@CDILoggerLoggerlogger; JAVA
@SvenRuppert 63/122
CDI explained by code
Qualifier und AnnotationsLiterale
@Inject@CDILoggerLoggerlogger; JAVA
@SvenRuppert 64/122
CDI explained by code
Qualifier und AnnotationsLiterale
@Inject@CDILoggerLoggerlogger; JAVA
@Producer@CDILoggerLoggercreate(...); JAVA
@SvenRuppert 65/122
CDI explained by code
Qualifier und AnnotationsLiterale
@Inject@CDILoggerLoggerlogger; JAVA
@Producer@CDILoggerLoggercreate(...); JAVA
@Producer@CDILoggerLoggercreate(..){
AnnotationsLiteral<T>prodAL=contextResolver.resolve(..);
};
JAVA
@SvenRuppert 66/122
CDI explained by code
Qualifier und AnnotationsLiterale
@Inject@CDILoggerLoggerlogger; JAVA
@Producer@CDILoggerLoggercreate(...); JAVA
@Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){
AnnotationsLiteral<T>prodAL=contextResolver.resolve(..);
returncreator.getManagedInstance(Logger.class,annotationLiteral);
};
JAVA
@SvenRuppert 67/122
CDI explained by code
Qualifier und AnnotationsLiterale
Es wird dynamisch auf ein AnnotationsLiteral aufgelöst.
@Inject@CDILoggerLoggerlogger; JAVA
@Producer@CDILoggerLoggercreate(...); JAVA
@Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){
AnnotationsLiteral<T>prodAL=contextResolver.resolve(..);
returncreator.getManagedInstance(Logger.class,annotationLiteral);
};
JAVA
@SvenRuppert 68/122
CDI explained by code
Qualifier und AnnotationsLiterale
Es wird dynamisch auf ein AnnotationsLiteral aufgelöst.
AnnotationsLiteral und Klasse -> Auswahl des Producers
@Inject@CDILoggerLoggerlogger; JAVA
@Producer@CDILoggerLoggercreate(...); JAVA
@Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){
AnnotationsLiteral<T>prodAL=contextResolver.resolve(..);
returncreator.getManagedInstance(Logger.class,annotationLiteral);
};
JAVA
@SvenRuppert 69/122
CDI explained by code 1 / 6
ContextResolver / aus der Sicht des Entwicklers
@InjectCDIContextcontext;//z.B.einSingleton
@InjectContextResolvercr;
@Test
publicvoidtestMockedModus001()throwsException{
Assert.assertFalse(context.isMockedModusActive());
finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass());
Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd);
}
JAVA
@SvenRuppert 70/122
CDI explained by code 1 / 6
ContextResolver / aus der Sicht des Entwicklers
@InjectCDIContextcontext;//z.B.einSingleton
@InjectContextResolvercr;
@Test
publicvoidtestMockedModus001()throwsException{
Assert.assertFalse(context.isMockedModusActive());
finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass());
Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd);
((TestContext)context).setTestModus(true);
Assert.assertTrue(context.isMockedModusActive());
}
JAVA
@SvenRuppert 71/122
CDI explained by code 1 / 6
ContextResolver / aus der Sicht des Entwicklers
@InjectCDIContextcontext;//z.B.einSingleton
@InjectContextResolvercr;
@Test
publicvoidtestMockedModus001()throwsException{
Assert.assertFalse(context.isMockedModusActive());
finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass());
Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd);
((TestContext)context).setTestModus(true);
Assert.assertTrue(context.isMockedModusActive());
finalAnnotationLiteralannotationLiteral=cr.resolveContext(this.getClass());
Assert.assertEquals(newAnnotationLiteral<CDICommonsMocked>(){},annotationLiteral);
}
JAVA
@SvenRuppert 72/122
CDI explained by code 1 / 6
ContextResolver / aus der Sicht des Entwicklers
@SvenRuppert 73/122
CDI explained by code 1 / 6
ContextResolver / aus der Sicht des Entwicklers
@SvenRuppert 74/122
CDI explained by code 2a / 6
ContextResolver
Die Annotation mit @CDINotMapped, um das Interface explizit in den
Namensraum zu setzen
@CDINotMapped
publicinterfaceCDIContext{
publicbooleanisMockedModusActive();
}
JAVA
@SvenRuppert 75/122
CDI explained by code 2b / 6
ContextResolver
Mit klassischen Interzeptoren kann man Querschnittsthemen deklarieren.
Nur allgemein umschalten auf Mocked/NotMocked möglich?
@InterceptorBinding
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)
@Inherited
public@interfaceCheckMockedContext{}
publicinterfaceContextResolver{
@CheckMockedContext
publicAnnotationLiteralresolveContext(finalClass<?>targetClass);
}
JAVA
@SvenRuppert 76/122
CDI explained by code 3a / 6
ContextResolver
@Interceptor@CheckMockedContext
publicclassMockedInterceptorimplementsSerializable{
@InjectCDIContextcontext;
private@Inject@CDILoggerLoggerlogger;
@AroundInvoke
publicObjectcheckMockedMode(InvocationContextctx)throwsException{
if(context.isMockedModusActive()){
if(logger.isDebugEnabled()){logger.debug("MockedModusactive");}
returnnewAnnotationLiteral<CDICommonsMocked>(){};
}else{
returnctx.proceed();
}
}
}
JAVA
@SvenRuppert 77/122
CDI explained by code 3b / 6
ContextResolver
Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar
@SvenRuppert 78/122
CDI explained by code 3b / 6
ContextResolver
Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar
Benötigt wird aber evtl differenziertes Umschalten.
@SvenRuppert 79/122
CDI explained by code 3b / 6
ContextResolver
Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar
Benötigt wird aber evtl differenziertes Umschalten.
Interzeptoren werden statisch definiert - schade....
@SvenRuppert 80/122
CDI explained by code 4a / 6
ContextResolver
@CDICommons
public class DefaultContextResolver implements ContextResolver {
@Inject @CDILogger Logger logger; @Inject BeanManager beanManager;
public Set<ContextResolver> gettAllContextResolver() {
final Set<ContextResolver> resultSet = new HashSet<>();
final Set<Bean<?>> allBeans = beanManager
.getBeans(ContextResolver.class, new AnnotationLiteral<Any>() {});
allBeans.forEach(b-> b.getTypes().stream()
.filter(t -> t.equals(ContextResolver.class))
.filter(r -> !r.getClass().isAnnotationPresent(CDICommonsMocked.class))
.forEach(t -> {
final ContextResolver cr = ((Bean<ContextResolver>) b)
.create(beanManager.createCreationalContext((Bean<ContextResolver>) b));
resultSet.add(cr);
}));
return resultSet;
}
JAVA
@SvenRuppert 81/122
CDI explained by code 4b / 6
ContextResolver
publicSet<ContextResolver>gettAllMockedContextResolver(){
finalSet<ContextResolver>resultSet=newHashSet<>();
finalSet<Bean<?>>allBeans=beanManager
.getBeans(ContextResolver.class,newAnnotationLiteral<CDICommonsMocked>(){});
allBeans.forEach(b->b.getTypes().forEach(type->{
if(type.equals(ContextResolver.class)){
finalContextResolvert=((Bean<ContextResolver>)b)
.create(beanManager.createCreationalContext((Bean<ContextResolver>)b));
resultSet.add(t);
}
}));
returnresultSet;
}
JAVA
@SvenRuppert 82/122
CDI explained by code 4c / 6
ContextResolver
publicAnnotationLiteralresolveContext(ClasstargetClass){
Stream<ContextResolver>contextResolversMocked=gettAllMockedContextResolver().stream();
Stream<ContextResolver>contextResolvers=gettAllContextResolver().stream();
returncontextResolversMocked
.filter(r->(r.resolveContext(targetClass)!=null))
.map(r->r.resolveContext(targetClass))
.findFirst().orElse(
contextResolvers
.filter(r->!r.getClass().isAnnotationPresent(CDICommonsMocked.class))
.filter(r->!r.getClass().equals(DefaultContextResolver.class))
.filter(r->(r.resolveContext(targetClass)!=null))
.map(r->r.resolveContext(targetClass))
.findFirst().orElse(null)
);
}
JAVA
@SvenRuppert 83/122
CDI explained by code 5 / 6
ContextResolver
@Singleton
publicclassTestContextimplementsCDIContext{
privatebooleantestModus=false;
@OverridepublicbooleanisMockedModusActive(){returntestModus;}
publicbooleanisTestModus(){returntestModus;}
publicvoidsetTestModus(booleantestModus){this.testModus=testModus;}
}
publicclassTestContextResolverimplementsContextResolver{
@InjectCDIContextcontext;
@CheckMockedContext
@OverridepublicAnnotationLiteralresolveContext(Class<?>targetClass){
//entscheideobDuzuständigbist
returnnewAnnotationLiteral<CDICommons>(){};
}
}
JAVA
@SvenRuppert 84/122
CDI explained by code 6 / 6
ContextResolver
Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren.
@SvenRuppert 85/122
CDI explained by code 6 / 6
ContextResolver
Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren.
ContextResolver sind immer nur in ihrem fachlichen Bereich aktiv
@SvenRuppert 86/122
CDI explained by code 6 / 6
ContextResolver
Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren.
ContextResolver sind immer nur in ihrem fachlichen Bereich aktiv
Unterscheidung auf z.B. Mandantenebene leicht realisierbar
@SvenRuppert 87/122
CDI explained by code 1 / 7
CDI managed DynamicObjectAdapter - besserer Decorator
klassischer Decorator in CDI
@Decorator
publicabstractclassCoderDecoratorimplementsCoder{
@Inject@Delegate@AnyCodercoder;
publicStringcodeString(Strings,inttval){
intlen=s.length();
return"""+s+""becomes"+"""+coder.codeString(s,tval)
+"","+len+"charactersinlength";
}
}
Insidebeans.xml
<decorators>
<class>decorators.CoderDecorator</class>
</decorators>
JAVA
@SvenRuppert 88/122
CDI explained by code 2 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Ein Decorator in CDI muss in der beans.xml definiert werden.
@SvenRuppert 89/122
CDI explained by code 2 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Ein Decorator in CDI muss in der beans.xml definiert werden.
Klasse mit einer speziellen Annotation @Decorator
@SvenRuppert 90/122
CDI explained by code 2 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Ein Decorator in CDI muss in der beans.xml definiert werden.
Klasse mit einer speziellen Annotation @Decorator
Innerhalb des Decorators muss die Instanz des Originals injiziert werden
@SvenRuppert 91/122
CDI explained by code 2 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Ein Decorator in CDI muss in der beans.xml definiert werden.
Klasse mit einer speziellen Annotation @Decorator
Innerhalb des Decorators muss die Instanz des Originals injiziert werden
Decorator muss von der Original-Implementierung oder dem Interface ableiten
@SvenRuppert 92/122
CDI explained by code 2 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Ein Decorator in CDI muss in der beans.xml definiert werden.
Klasse mit einer speziellen Annotation @Decorator
Innerhalb des Decorators muss die Instanz des Originals injiziert werden
Decorator muss von der Original-Implementierung oder dem Interface ableiten
... geht das auch schöner ?
@SvenRuppert 93/122
CDI explained by code 3 / 7
CDI managed DynamicObjectAdapter - der bessere Decorator
Aus der Sicht des Entwicklers
@CDINotMapped
publicinterfaceDemoLogic{
publicdefaultintadd(inta,intb){ returna+b;}
publicdefaultintsub(inta,intb){ returna-b;}
}
@CDINotMapped
publicclassDemoLogicAdapter_AimplementsDemoLogic{
publicintadd(inta,intb){
returna+b+100;
}
}
@Singleton //sollteschonbekanntsein;-)
publicclassContext{publicbooleanoriginal=true;}
JAVA
@SvenRuppert 94/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
@SvenRuppert 95/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
@SvenRuppert 96/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
@SvenRuppert 97/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
@SvenRuppert 98/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
Context-Switch auf mandantenabhängige Implementierung
@SvenRuppert 99/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
Context-Switch auf mandantenabhängige Implementierung
Holen einer Instanz der DemoLogic
@SvenRuppert 100/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
Context-Switch auf mandantenabhängige Implementierung
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
@SvenRuppert 101/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
Context-Switch auf mandantenabhängige Implementierung
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 102.
@SvenRuppert 102/122
CDI explained by code 4a / 7
CDI managed DynamicObjectAdapter - besserer Decorator
Injizieren der Referenz auf DemoLogic
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
Context-Switch auf mandantenabhängige Implementierung
Holen einer Instanz der DemoLogic
Aufruf der Methode add(1,1)
Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 102.
Kaffee trinken.
@SvenRuppert 103/122
CDI explained by code 4b / 7
CDI managed DynamicObjectAdapter - besserer Decorator
@Inject@DynamicDecoratorTestInstance<DemoLogic>demoLogic;
@InjectContextcontext;
@Test
publicvoidtestDemoLogicOriginalTest()throwsException{
Assert.assertNotNull(demoLogic);
finalDemoLogicdemoLogic1=demoLogic.get();
finalintadd=demoLogic1.add(1,1);
Assert.assertEquals(2,add);
System.out.println("add="+add);
context.original=false;
finalDemoLogicdemoLogic2=demoLogic.get();
finalintaddAdapted=demoLogic2.add(1,1);
Assert.assertEquals(102,addAdapted);
System.out.println("addAdapted="+addAdapted);
}
JAVA
@SvenRuppert 104/122
CDI explained by code 4c / 7
CDI managed DynamicObjectAdapter - besserer Decorator
manuelles aktivieren von CDI.. yepp das geht
public<T>TactivateCDI(Tt){
finalClassaClass=t.getClass();
if(logger.isDebugEnabled()){logger.debug("activateCDI->"+aClass);}
AnnotatedTypeannotationType=beanManager.createAnnotatedType(aClass);
InjectionTargetinjectionTarget=beanManager.createInjectionTarget(annotationType);
CreationalContextcreationalContext=beanManager.createCreationalContext(null);
injectionTarget.inject(t,creationalContext);
injectionTarget.postConstruct(t);
returnt;
}
JAVA
@SvenRuppert 105/122
CDI explained by code 5 / 7
CDI managed DynamicObjectAdapter - besserer Decorator
public class DemoLogicProducer {
@Inject Instance<DynamicObjectAdapterFactory> dOAFInstance;
@Inject Context context;
@Produces @DynamicDecoratorTest
public DemoLogic create(ManagedInstanceCreator instanceCreator){
final DemoLogic demoLogic = instanceCreator.activateCDI(new DemoLogic() {});
final DynamicObjectAdapterFactory dynamicObjectAdapterFactory = dOAFInstance.get();
final Object adapter;
if (context.original){ adapter = new Object(); }
else { //kann hier beliebig komplex werden
adapter = instanceCreator.activateCDI(new DemoLogicAdapter_A());
}
//hier interface notwendig... see insight
return dynamicObjectAdapterFactory.adapt(demoLogic, DemoLogic.class, adapter);
}
JAVA
@SvenRuppert 106/122
CDI explained by code 6 / 7
CDI managed DynamicObjectAdapter - besserer Decorator
publicclassDynamicObjectAdapterFactory{
@InjectInstance<CDIInvocationHandler>cdiInvocationHandlerInstance;
public<T>Tadapt(finalObjectadaptee,finalClass<T>target,finalObjectadapter){
finalCDIInvocationHandlerinvocationHandler=
cdiInvocationHandlerInstance.get().adapter(adapter).adaptee(adaptee);
return(T)Proxy.newProxyInstance(
target.getClassLoader(),
newClass[]{target}, //hierInterfacenotwendig!
invocationHandler
);
}
}
JAVA
@SvenRuppert 107/122
CDI explained by code 7a / 7c
CDI managed DynamicObjectAdapter - besserer Decorator
publicclassMethodIdentifier{
privatefinalStringname;
privatefinalClass[]parameters;
publicMethodIdentifier(Methodm){
name=m.getName();parameters=m.getParameterTypes();
}
//wecansavetimebyassumingthatweonlycompareagainst
//otherMethodIdentifierobjects
publicbooleanequals(Objecto){
MethodIdentifiermid=(MethodIdentifier)o;
returnname.equals(mid.name)&&Arrays.equals(parameters,mid.parameters);
}
publicinthashCode(){ returnname.hashCode();}
}
JAVA
@SvenRuppert 108/122
CDI explained by code 7b / 7c
CDI managed DynamicObjectAdapter - besserer Decorator
publicclassCDIInvocationHandlerimplementsInvocationHandler{
privateMap<MethodIdentifier,Method>adaptedMethods=newHashMap<>();
privateObjectadapter;privateObjectadaptee;
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
if(adaptedMethods.isEmpty()){
Method[]methods=adapter.getClass().getDeclaredMethods();
for(Methodm:methods){ adaptedMethods.put(newMethodIdentifier(m),m);}
}
try{
Methodother=adaptedMethods.get(newMethodIdentifier(method));
if(other!=null) {returnother.invoke(adapter,args);}
else {returnmethod.invoke(adaptee,args); }
}catch(InvocationTargetExceptione){throwe.getTargetException();}
}...
JAVA
@SvenRuppert 109/122
CDI explained by code 7c / 7c
CDI managed DynamicObjectAdapter - besserer Decorator
Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI
Decorators auszugleichen.
@SvenRuppert 110/122
CDI explained by code 7c / 7c
CDI managed DynamicObjectAdapter - besserer Decorator
Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI
Decorators auszugleichen.
Spätere Änderungen an dem Interface führen nicht dazu, dass alle Adapter
angepasst werden müssen
@SvenRuppert 111/122
CDI explained by code 7c / 7c
CDI managed DynamicObjectAdapter - besserer Decorator
Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI
Decorators auszugleichen.
Spätere Änderungen an dem Interface führen nicht dazu, dass alle Adapter
angepasst werden müssen
Alle Komponenten sind von dem verwendeten CDI-Container verwaltet
@SvenRuppert 112/122
Cross Language Injection
.. am Beispiel von Kotlin..
classDemoLogicKotlin(){
publicfunworkOnString():String{
return"DemoLogicKotlin"
}
}
JAVA
@SvenRuppert 113/122
Cross Language Injection
.. am Beispiel von Kotlin..
entweder : Adapter mit Delegator
@CDINotMapped
publicclassDemoLogicKotlinWrapperimplementsDemoLogic{
private@InjectDemoLogicKotlinkotlin;
publicStringworkOnString(){
returnkotlin.workOnString();
}
}
JAVA
@SvenRuppert 114/122
Cross Language Injection
.. am Beispiel von Kotlin..
oder mittels Producer direkt verfügbar machen
@CDINotMapped
publicclassDemoLogicKotlinProducer{
@InjectManagedInstanceCreatorcreator;
//@InjectDemoLogicKotlinkotlin;
@Produces@KotlinImpl
publicDemoLogiccreate(){
finalDemoLogiclogic=newDemoLogicKotlinWrapper();
returncreator.activateCDI(logic);
}
}
JAVA
@SvenRuppert 115/122
CDI und TDD
... kaskadierte MOCKS
Service A injected Service B injected Service C
@SvenRuppert 116/122
CDI und TDD
... kaskadierte MOCKS
Service A injected Service B injected Service C
Service A (mocked) injected Service B injected Service C
@SvenRuppert 117/122
CDI und TDD
... kaskadierte MOCKS
Service A injected Service B injected Service C
Service A (mocked) injected Service B injected Service C
Service A injected Service B (mocked) injected Service C
@SvenRuppert 118/122
CDI und TDD
... kaskadierte MOCKS
Service A injected Service B injected Service C
Service A (mocked) injected Service B injected Service C
Service A injected Service B (mocked) injected Service C
Service A (mocked) injected Service B (mocked) injected Service C
@SvenRuppert 119/122
CDI und TDD
... kaskadierte MOCKS
Service A injected Service B injected Service C
Service A (mocked) injected Service B injected Service C
Service A injected Service B (mocked) injected Service C
Service A (mocked) injected Service B (mocked) injected Service C
beliebige Kombinationen können so dynamisch zusammen geschaltet werden.
@SvenRuppert 120/122
finally at amazon..
my book with Dr, Heinz Kabutz
Book about Reflection - part one
Dynamic Proxies z.B. ...dynamic static proxies... ;-)
<Thank You!>
g+ www.google.com/+SvenRuppert
twitter @SvenRuppert
www www.rapidpm.org
www www.rapidpm.org
github github.com/svenruppert

Contenu connexe

Similaire à Warum ich so auf das c von cdi stehe

Legacy Code refaktorisieren
Legacy Code refaktorisierenLegacy Code refaktorisieren
Legacy Code refaktorisierenHendrik Lösch
 
Sensitive Daten in der Oracle Datenbank
Sensitive Daten in der Oracle DatenbankSensitive Daten in der Oracle Datenbank
Sensitive Daten in der Oracle DatenbankUlrike Schwinn
 
The Lotus Code Cookbook
The Lotus Code CookbookThe Lotus Code Cookbook
The Lotus Code CookbookUlrich Krause
 
Funktionale Reaktive Programmierung mit Sodium
Funktionale Reaktive Programmierung mit SodiumFunktionale Reaktive Programmierung mit Sodium
Funktionale Reaktive Programmierung mit SodiumTorsten Fink
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPAmh0708
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptSebastian Springer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Stephan Hochdörfer
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenAndré Goliath
 
C++ Dependency Management 2.0
C++ Dependency Management 2.0C++ Dependency Management 2.0
C++ Dependency Management 2.0Patrick Charrier
 
Dataservices - Data Processing mit Microservices
Dataservices - Data Processing mit MicroservicesDataservices - Data Processing mit Microservices
Dataservices - Data Processing mit MicroservicesQAware GmbH
 
Citrix Day 2014: Panalpina - global und doch nah
Citrix Day 2014: Panalpina - global und doch nahCitrix Day 2014: Panalpina - global und doch nah
Citrix Day 2014: Panalpina - global und doch nahDigicomp Academy AG
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Josef Adersberger
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?QAware GmbH
 
Große Applikationen mit AngularJS
Große Applikationen mit AngularJSGroße Applikationen mit AngularJS
Große Applikationen mit AngularJSSebastian Springer
 
Article - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerArticle - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerWolfgang Weigend
 
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?Trivadis
 
Feedback-Loops in der ABAP Softwareentwicklung
Feedback-Loops in der ABAP SoftwareentwicklungFeedback-Loops in der ABAP Softwareentwicklung
Feedback-Loops in der ABAP SoftwareentwicklungPascal_Erni
 
Migration zum Zend Framework 3
Migration zum Zend Framework 3Migration zum Zend Framework 3
Migration zum Zend Framework 3Ralf Eggert
 

Similaire à Warum ich so auf das c von cdi stehe (20)

Legacy Code refaktorisieren
Legacy Code refaktorisierenLegacy Code refaktorisieren
Legacy Code refaktorisieren
 
Sensitive Daten in der Oracle Datenbank
Sensitive Daten in der Oracle DatenbankSensitive Daten in der Oracle Datenbank
Sensitive Daten in der Oracle Datenbank
 
The Lotus Code Cookbook
The Lotus Code CookbookThe Lotus Code Cookbook
The Lotus Code Cookbook
 
Funktionale Reaktive Programmierung mit Sodium
Funktionale Reaktive Programmierung mit SodiumFunktionale Reaktive Programmierung mit Sodium
Funktionale Reaktive Programmierung mit Sodium
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 
Production-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 WochenProduction-ready Infrastruktur in 3 Wochen
Production-ready Infrastruktur in 3 Wochen
 
C++ Dependency Management 2.0
C++ Dependency Management 2.0C++ Dependency Management 2.0
C++ Dependency Management 2.0
 
Dataservices - Data Processing mit Microservices
Dataservices - Data Processing mit MicroservicesDataservices - Data Processing mit Microservices
Dataservices - Data Processing mit Microservices
 
Citrix Day 2014: Panalpina - global und doch nah
Citrix Day 2014: Panalpina - global und doch nahCitrix Day 2014: Panalpina - global und doch nah
Citrix Day 2014: Panalpina - global und doch nah
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?
 
Große Applikationen mit AngularJS
Große Applikationen mit AngularJSGroße Applikationen mit AngularJS
Große Applikationen mit AngularJS
 
Article - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der EntwicklerArticle - JDK 8 im Fokus der Entwickler
Article - JDK 8 im Fokus der Entwickler
 
SpiraTeam im Überblick
SpiraTeam im ÜberblickSpiraTeam im Überblick
SpiraTeam im Überblick
 
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?
Wie kommt der Hint in das SQL, ohne die anwendung zu ändern?
 
Feedback-Loops in der ABAP Softwareentwicklung
Feedback-Loops in der ABAP SoftwareentwicklungFeedback-Loops in der ABAP Softwareentwicklung
Feedback-Loops in der ABAP Softwareentwicklung
 
Migration zum Zend Framework 3
Migration zum Zend Framework 3Migration zum Zend Framework 3
Migration zum Zend Framework 3
 
Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1
 

Plus de Sven Ruppert

JUnit5 Custom TestEngines intro - version 2020-06
JUnit5 Custom TestEngines intro - version 2020-06JUnit5 Custom TestEngines intro - version 2020-06
JUnit5 Custom TestEngines intro - version 2020-06Sven Ruppert
 
Hidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceHidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceSven Ruppert
 
Vaadin Flow - How to start - a short intro for Java Devs
Vaadin Flow - How to start - a short intro for Java DevsVaadin Flow - How to start - a short intro for Java Devs
Vaadin Flow - How to start - a short intro for Java DevsSven Ruppert
 
Functional Reactive With Core Java - Voxxed Melbourne
Functional Reactive With Core Java - Voxxed MelbourneFunctional Reactive With Core Java - Voxxed Melbourne
Functional Reactive With Core Java - Voxxed MelbourneSven Ruppert
 
Functional Reactive with Core Java - Workshop - Slides
Functional Reactive with Core Java - Workshop - SlidesFunctional Reactive with Core Java - Workshop - Slides
Functional Reactive with Core Java - Workshop - SlidesSven Ruppert
 
Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001Sven Ruppert
 
From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017Sven Ruppert
 
From Jurassic Park to Microservices
From Jurassic Park to MicroservicesFrom Jurassic Park to Microservices
From Jurassic Park to MicroservicesSven Ruppert
 
From jUnit to Mutationtesting
From jUnit to MutationtestingFrom jUnit to Mutationtesting
From jUnit to MutationtestingSven Ruppert
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearlsSven Ruppert
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Sven Ruppert
 
Java8 ready for the future
Java8 ready for the futureJava8 ready for the future
Java8 ready for the futureSven Ruppert
 
JavaFX8 TestFX - CDI
JavaFX8   TestFX - CDIJavaFX8   TestFX - CDI
JavaFX8 TestFX - CDISven Ruppert
 
Java FX8 JumpStart - JUG ch - zürich
Java FX8   JumpStart - JUG ch - zürichJava FX8   JumpStart - JUG ch - zürich
Java FX8 JumpStart - JUG ch - zürichSven Ruppert
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Sven Ruppert
 
Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Sven Ruppert
 

Plus de Sven Ruppert (16)

JUnit5 Custom TestEngines intro - version 2020-06
JUnit5 Custom TestEngines intro - version 2020-06JUnit5 Custom TestEngines intro - version 2020-06
JUnit5 Custom TestEngines intro - version 2020-06
 
Hidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-PersistenceHidden pearls for High-Performance-Persistence
Hidden pearls for High-Performance-Persistence
 
Vaadin Flow - How to start - a short intro for Java Devs
Vaadin Flow - How to start - a short intro for Java DevsVaadin Flow - How to start - a short intro for Java Devs
Vaadin Flow - How to start - a short intro for Java Devs
 
Functional Reactive With Core Java - Voxxed Melbourne
Functional Reactive With Core Java - Voxxed MelbourneFunctional Reactive With Core Java - Voxxed Melbourne
Functional Reactive With Core Java - Voxxed Melbourne
 
Functional Reactive with Core Java - Workshop - Slides
Functional Reactive with Core Java - Workshop - SlidesFunctional Reactive with Core Java - Workshop - Slides
Functional Reactive with Core Java - Workshop - Slides
 
Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001Functional reactive-talk 20170301-001
Functional reactive-talk 20170301-001
 
From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017
 
From Jurassic Park to Microservices
From Jurassic Park to MicroservicesFrom Jurassic Park to Microservices
From Jurassic Park to Microservices
 
From jUnit to Mutationtesting
From jUnit to MutationtestingFrom jUnit to Mutationtesting
From jUnit to Mutationtesting
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearls
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
Java8 ready for the future
Java8 ready for the futureJava8 ready for the future
Java8 ready for the future
 
JavaFX8 TestFX - CDI
JavaFX8   TestFX - CDIJavaFX8   TestFX - CDI
JavaFX8 TestFX - CDI
 
Java FX8 JumpStart - JUG ch - zürich
Java FX8   JumpStart - JUG ch - zürichJava FX8   JumpStart - JUG ch - zürich
Java FX8 JumpStart - JUG ch - zürich
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02
 
Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015
 

Warum ich so auf das c von cdi stehe

  • 1. Warum CDI oder gibt es einen tieferen Sinn dahinter? warum denn CDI ? ;-)
  • 2. @SvenRuppert 4/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? oft gehörte Antwort kürzere Notation.. *oje* Manchmal ist die Notation per Inject kürzer. Sobald allerdings die einzelnen Qualifier dazukommen, ist meist der Aufwand zum Aufruf eines Konstruktors kaum unterschiedlich. Verkürzen der Notation ist natürlich nicht das Ziel von CDI
  • 3. @SvenRuppert 5/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? lösen/entfernen von statischen Abhängigkeiten
  • 4. @SvenRuppert 6/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? lösen/entfernen von statischen Abhängigkeiten Dieser Punkt ist einer der wesentlichen. Also: Wie kann man zur Entwicklungszeit die Abhängigkeiten zu den anderen Projektmodulen möglichst gering halten?
  • 5. @SvenRuppert 7/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? lösen/entfernen von statischen Abhängigkeiten Dieser Punkt ist einer der wesentlichen. Also: Wie kann man zur Entwicklungszeit die Abhängigkeiten zu den anderen Projektmodulen möglichst gering halten? Gehen wir von der Definition einer Liste aus. Als Rückgabewert einer Methode wird eine Instanz der Implementierung von List verwendet. publicList<Data>execute(){...}; JAVA
  • 6. @SvenRuppert 8/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Damit sind nachfolgende Aufrufer nicht mehr an die Implementierung der List gebunden. importjava.util.List; importjava.util.ArrayList; publicList<Data>execute(){ finalList<Data>result=newArrayList<>(); //.... returnresult; } JAVA
  • 7. @SvenRuppert 9/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Damit sind nachfolgende Aufrufer nicht mehr an die Implementierung der List gebunden. In der Methode jedoch besteht meist die Abhängigkeit zu der entsprechenden Implementierung obwohl auch das meist nicht notwendig ist. importjava.util.List; importjava.util.ArrayList; publicList<Data>execute(){ finalList<Data>result=newArrayList<>(); //.... returnresult; } JAVA
  • 8. @SvenRuppert 10/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet.
  • 9. @SvenRuppert 11/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet. Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig.
  • 10. @SvenRuppert 12/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet. Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig. Sollte sich zur Laufzeit herausstellen, das die Wahl dieser Implementierung nicht optimal gewesen ist, muss der Quelltext angepasst und neu verteilt werden.
  • 11. @SvenRuppert 13/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet. Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig. Sollte sich zur Laufzeit herausstellen, das die Wahl dieser Implementierung nicht optimal gewesen ist, muss der Quelltext angepasst und neu verteilt werden. z.B. Mit std SE Mitteln kann man das durch entsprechende Factories lösen.
  • 12. @SvenRuppert 14/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Mit std SE Mitteln kann man das durch entsprechende Factories lösen. Beispielhaft soll hier folgende Implementierung verwendet werden. importjava.util.ArrayList; importjava.util.LinkedList; importjava.util.List; publicclassListFactory{ publicListcreateArrayList() {returnnewArrayList();} publicListcreateLinkedList(){returnnewLinkedList();} publicListcreateList() {returnnewArrayList();} } JAVA
  • 13. @SvenRuppert 15/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Haben wir damit etwas erreicht?
  • 14. @SvenRuppert 16/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Haben wir damit etwas erreicht? ... bzw was haben wir damit erreicht?
  • 15. @SvenRuppert 17/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Haben wir damit etwas erreicht? ... bzw was haben wir damit erreicht? z.B. Die Entwickler verwenden nun diese Factory.
  • 16. @SvenRuppert 18/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Haben wir damit etwas erreicht? ... bzw was haben wir damit erreicht? z.B. Die Entwickler verwenden nun diese Factory. -> wenn sie wissen das es diese gibt! ;-)
  • 17. @SvenRuppert 19/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Vorher / Nachher (1/2) importjava.util.List; importjava.util.ArrayList; publicList<Data>execute(){ finalList<Data>result=newArrayList<>(); //.... returnresult; } JAVA
  • 18. @SvenRuppert 20/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Vorher / Nachher (2/2) importjava.util.List; importjava.util.ArrayList; publicList<Data>execute(){ finalList<Data>result=newArrayList<>(); //.... returnresult; } importjava.util.List; importorg.rapidpm.demo.ListFactory; publicList<Data>execute(){ finalListlist=newListFactory().createArrayList(); //.... returnresult; } JAVA
  • 19. @SvenRuppert 21/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert.
  • 20. @SvenRuppert 22/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert. Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit gefallen.
  • 21. @SvenRuppert 23/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert. Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit gefallen. Die Abhängigkeit zur Factory wurde hinzugefügt.
  • 22. @SvenRuppert 24/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert. Die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch explizit gefallen. Die Abhängigkeit zur Factory wurde hinzugefügt. Die Implementierung der ListFactory selber hat auch wieder die statischen Abhängigkeiten zu allen vorgesehenen Implementierungen.
  • 23. @SvenRuppert 25/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen Implementierungen
  • 24. @SvenRuppert 26/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen Implementierungen Anforderung Nr 2: keine statischen Entscheidungen für spezifische Implementierungen
  • 25. @SvenRuppert 27/122 Warum CDI oder gibt es einen tieferen Sinn dahinter? Anforderung Nr 1: keine statischen Abhängigkeiten zu spezifischen Implementierungen Anforderung Nr 2: keine statischen Entscheidungen für spezifische Implementierungen Was ist jetzt eine mögliche Lösung ???
  • 26. @SvenRuppert 28/122 Lösungsversuch Nr 1 basierend auf Java SE Eine etwas dynamischere Lösung...
  • 27. @SvenRuppert 29/122 Lösungsversuch Nr 1 basierend auf Java SE Eine etwas dynamischere Lösung... importjava.util.ArrayList; importjava.util.LinkedList; importjava.util.List; importorg.rapidpm.demo.cdi.commons.registry.ContextResolver; publicclassListFactory{ publicListcreateList(finalContextResolvercontextResolver){ if(contextResolver==null){returncreateArrayList();} else{ if(contextResolver.resolveContext()){returncreateArrayList();} else{returncreateLinkedList();} } } } JAVA
  • 28. @SvenRuppert 30/122 Lösungsversuch Nr 1 basierend auf Java SE Eine etwas dynamischere Lösung... Die Komplexität der Entscheidung liegt nun im ContextResolver
  • 29. @SvenRuppert 31/122 Lösungsversuch Nr 1 basierend auf Java SE Eine etwas dynamischere Lösung... Die Komplexität der Entscheidung liegt nun im ContextResolver Abhängigkeit in der Factory zum ContextResolver hinzugefügt
  • 30. @SvenRuppert 32/122 Lösungsversuch Nr 1 basierend auf Java SE Eine etwas dynamischere Lösung... Die Komplexität der Entscheidung liegt nun im ContextResolver Abhängigkeit in der Factory zum ContextResolver hinzugefügt Gewonnen: zur Laufzeit sich für eine Implementierung entscheiden.
  • 31. @SvenRuppert 33/122 Lösungsversuch Nr 1 basierend auf Java SE Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste hat, muss eine z.B. Registry gebaut werden.
  • 32. @SvenRuppert 34/122 Lösungsversuch Nr 1 basierend auf Java SE Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste hat, muss eine z.B. Registry gebaut werden. Dort kann man zur Laufzeit die jeweiligen Implementierungen registrieren und für eine Auflösung zur Verfügung stellen.
  • 33. @SvenRuppert 35/122 Lösungsversuch Nr 1 basierend auf Java SE Möchte man nun die Factory so erstellen, dass diese wiederum keine statischen Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste hat, muss eine z.B. Registry gebaut werden. Dort kann man zur Laufzeit die jeweiligen Implementierungen registrieren und für eine Auflösung zur Verfügung stellen. Hier hilft CDI durch seine Konzepte, ohne das man sich mit der Basisimplementierung der Infrastruktur beschäftigen muss.
  • 34. @SvenRuppert 36/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt
  • 35. @SvenRuppert 37/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt @InjectListlist; JAVA
  • 36. @SvenRuppert 38/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt @Inject@CDILegacyTestListlist; JAVA
  • 37. @SvenRuppert 39/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt @Inject@CDILegacyTestListlist; @Produces@CDILegacyTest publicListcreateList(...){...} JAVA
  • 38. @SvenRuppert 40/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt @Inject@CDILegacyTestListlist; @Produces@CDILegacyTest publicListcreateList(InjectionPointinjectionPoint, BeanManagerbeanManager,ContextResolvercontextResolver){ .... } JAVA
  • 39. @SvenRuppert 41/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt @Inject@CDILegacyTestListlist; @Produces@CDILegacyTest publicListcreateList(InjectionPointinjectionPoint, BeanManagerbeanManager,ContextResolvercontextResolver){ booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen... if(b){returnnewLinkedList();}else{returnnewArrayList();} } JAVA
  • 40. @SvenRuppert 42/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen werden per @Inject durch den Container zur Verfügung gestellt Aber leider ist das immer noch zu dem Zeitpunkt zu dem die umliegende Instanz erzeugt wird. @Inject@CDILegacyTestListlist; @Produces@CDILegacyTest publicListcreateList(InjectionPointinjectionPoint, BeanManagerbeanManager,ContextResolvercontextResolver){ booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen... if(b){returnnewLinkedList();}else{returnnewArrayList();} } JAVA
  • 41. @SvenRuppert 43/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden.
  • 42. @SvenRuppert 44/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden. Damit sind späte Entscheidungen möglich
  • 43. @SvenRuppert 45/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden. Damit sind späte Entscheidungen möglich @Inject@CDILegacyTestInstance<List>listInstance; JAVA
  • 44. @SvenRuppert 46/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden. Damit sind späte Entscheidungen möglich @Inject@CDILegacyTestInstance<List>listInstance; //..später finalListlist=listInstance.get(); JAVA
  • 45. @SvenRuppert 47/122 endlich CDI ;-) basierend auf Weld / WELD-SE Instanzen können auch erst zum Zeitpunkt der Verwendung instanziiert werden damit sind späte Entscheidungen möglich @Inject@CDILegacyTestInstance<List>listInstance; //..später finalListlist=listInstance.get(); @Produces@CDILegacyTest publicListcreateList(InjectionPointinjectionPoint, BeanManagerbeanManager,ContextResolvercontextResolver){ booleanb=contextResolver.resolveContext(...); //treffenderEntscheidungen... if(b){returnnewLinkedList();}else{returnnewArrayList();} } JAVA
  • 46. @SvenRuppert 48/122 CDI was wurde bis jetzt erreicht? Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der Vererbung
  • 47. @SvenRuppert 49/122 CDI was wurde bis jetzt erreicht? Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der Vererbung Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt
  • 48. @SvenRuppert 50/122 CDI was wurde bis jetzt erreicht? Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der Vererbung Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt Für jede Entscheidung einen Producer
  • 49. @SvenRuppert 51/122 CDI was wurde bis jetzt erreicht? Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der Vererbung Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt Für jede Entscheidung einen Producer.. wie funktioniert das praktisch?
  • 50. @SvenRuppert 52/122 CDI was wurde bis jetzt erreicht? Trennung der statischen Abhängigkeiten auf Klassenebene innerhalb der Vererbung Keine "allwissende" Factory, die alle statischen Abhängigkeiten besitzt Für jede Entscheidung einen Producer.. wie funktioniert das praktisch? ... sehen wir uns gleich noch an.... Bitte ein wenig Geduld...
  • 51. @SvenRuppert 53/122 CDI was wurde dafür in Kauf genommen? statische Kopplung über AnnotationsLiterale: @Inject@MyQualifierListliste; JAVA
  • 52. @SvenRuppert 54/122 CDI was wurde dafür in Kauf genommen? statische Kopplung über AnnotationsLiterale: schlechterer Umgang mit Generics @Inject@MyQualifierListliste; JAVA
  • 53. @SvenRuppert 55/122 CDI was wurde dafür in Kauf genommen? statische Kopplung über AnnotationsLiterale: schlechterer Umgang mit Generics keine Komplexitätsreduktion für den Entwickler @Inject@MyQualifierListliste; JAVA
  • 54. @SvenRuppert 56/122 CDI explained by code HelloLogger zum aufwärmen/wiederholen klassischer Fall, Logger im System @Inject@CDILoggerLoggerlogger; JAVA
  • 55. @SvenRuppert 57/122 CDI explained by code HelloLogger zum aufwärmen/wiederholen klassischer Fall, Logger im System @Inject@CDILoggerLoggerlogger; @Qualifier @Retention(value=RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE}) public@interfaceCDILogger{} JAVA
  • 56. @SvenRuppert 58/122 CDI explained by code HelloLogger zum aufwärmen/wiederholen klassischer Fall, Logger im System @Inject@CDILoggerLoggerlogger; @Qualifier @Retention(value=RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE}) public@interfaceCDILogger{} @Produces@CDILogger publicLoggerproduceLog4JLogger(InjectionPointiP,BeanManagerbeanManager){ finalClass<?>declaringClass=iP.getMember().getDeclaringClass(); returnnewLogger(declaringClass); } JAVA
  • 57. @SvenRuppert 59/122 CDI explained by code HelloLogger zum aufwärmen/wiederholen klassischer Fall, Logger im System @Inject@CDILoggerLoggerlogger; @Qualifier @Retention(value=RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE}) public@interfaceCDILogger{} @Produces@CDILogger publicLoggerproduceLog4JLogger(InjectionPointiP,BeanManagerbeanManager){ finalClass<?>declaringClass=iP.getMember().getDeclaringClass(); returnnewLogger(declaringClass);//Loggernichtgemanaged!!! } JAVA
  • 58. @SvenRuppert 60/122 CDI explained by code HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht? Referenz auf Factory wird ersetzt durch Qualifier. :-( @Inject@CDILoggerLoggerlogger; JAVA
  • 59. @SvenRuppert 61/122 CDI explained by code HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht? Referenz auf Factory wird ersetzt durch Qualifier. :-( Spezifische Producer losgelöst von den anderen Producern @Inject@CDILoggerLoggerlogger; JAVA
  • 60. @SvenRuppert 62/122 CDI explained by code HelloLogger zum aufwärmen / Hat uns das jetzt richtig weitergebracht? Referenz auf Factory wird ersetzt durch Qualifier. :-( Spezifische Producer losgelöst von den anderen Producern zentrale Stelle für context-bezogene Entscheidungen @Inject@CDILoggerLoggerlogger; JAVA
  • 61. @SvenRuppert 63/122 CDI explained by code Qualifier und AnnotationsLiterale @Inject@CDILoggerLoggerlogger; JAVA
  • 62. @SvenRuppert 64/122 CDI explained by code Qualifier und AnnotationsLiterale @Inject@CDILoggerLoggerlogger; JAVA @Producer@CDILoggerLoggercreate(...); JAVA
  • 63. @SvenRuppert 65/122 CDI explained by code Qualifier und AnnotationsLiterale @Inject@CDILoggerLoggerlogger; JAVA @Producer@CDILoggerLoggercreate(...); JAVA @Producer@CDILoggerLoggercreate(..){ AnnotationsLiteral<T>prodAL=contextResolver.resolve(..); }; JAVA
  • 64. @SvenRuppert 66/122 CDI explained by code Qualifier und AnnotationsLiterale @Inject@CDILoggerLoggerlogger; JAVA @Producer@CDILoggerLoggercreate(...); JAVA @Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){ AnnotationsLiteral<T>prodAL=contextResolver.resolve(..); returncreator.getManagedInstance(Logger.class,annotationLiteral); }; JAVA
  • 65. @SvenRuppert 67/122 CDI explained by code Qualifier und AnnotationsLiterale Es wird dynamisch auf ein AnnotationsLiteral aufgelöst. @Inject@CDILoggerLoggerlogger; JAVA @Producer@CDILoggerLoggercreate(...); JAVA @Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){ AnnotationsLiteral<T>prodAL=contextResolver.resolve(..); returncreator.getManagedInstance(Logger.class,annotationLiteral); }; JAVA
  • 66. @SvenRuppert 68/122 CDI explained by code Qualifier und AnnotationsLiterale Es wird dynamisch auf ein AnnotationsLiteral aufgelöst. AnnotationsLiteral und Klasse -> Auswahl des Producers @Inject@CDILoggerLoggerlogger; JAVA @Producer@CDILoggerLoggercreate(...); JAVA @Producer@CDILoggerLoggercreate(BeanManagerbm,ContextResolvercr){ AnnotationsLiteral<T>prodAL=contextResolver.resolve(..); returncreator.getManagedInstance(Logger.class,annotationLiteral); }; JAVA
  • 67. @SvenRuppert 69/122 CDI explained by code 1 / 6 ContextResolver / aus der Sicht des Entwicklers @InjectCDIContextcontext;//z.B.einSingleton @InjectContextResolvercr; @Test publicvoidtestMockedModus001()throwsException{ Assert.assertFalse(context.isMockedModusActive()); finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass()); Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd); } JAVA
  • 68. @SvenRuppert 70/122 CDI explained by code 1 / 6 ContextResolver / aus der Sicht des Entwicklers @InjectCDIContextcontext;//z.B.einSingleton @InjectContextResolvercr; @Test publicvoidtestMockedModus001()throwsException{ Assert.assertFalse(context.isMockedModusActive()); finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass()); Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd); ((TestContext)context).setTestModus(true); Assert.assertTrue(context.isMockedModusActive()); } JAVA
  • 69. @SvenRuppert 71/122 CDI explained by code 1 / 6 ContextResolver / aus der Sicht des Entwicklers @InjectCDIContextcontext;//z.B.einSingleton @InjectContextResolvercr; @Test publicvoidtestMockedModus001()throwsException{ Assert.assertFalse(context.isMockedModusActive()); finalAnnotationLiteralannotationLiteralProd=cr.resolveContext(this.getClass()); Assert.assertEquals(newAnnotationLiteral<CDICommons>(){},annotationLiteralProd); ((TestContext)context).setTestModus(true); Assert.assertTrue(context.isMockedModusActive()); finalAnnotationLiteralannotationLiteral=cr.resolveContext(this.getClass()); Assert.assertEquals(newAnnotationLiteral<CDICommonsMocked>(){},annotationLiteral); } JAVA
  • 70. @SvenRuppert 72/122 CDI explained by code 1 / 6 ContextResolver / aus der Sicht des Entwicklers
  • 71. @SvenRuppert 73/122 CDI explained by code 1 / 6 ContextResolver / aus der Sicht des Entwicklers
  • 72. @SvenRuppert 74/122 CDI explained by code 2a / 6 ContextResolver Die Annotation mit @CDINotMapped, um das Interface explizit in den Namensraum zu setzen @CDINotMapped publicinterfaceCDIContext{ publicbooleanisMockedModusActive(); } JAVA
  • 73. @SvenRuppert 75/122 CDI explained by code 2b / 6 ContextResolver Mit klassischen Interzeptoren kann man Querschnittsthemen deklarieren. Nur allgemein umschalten auf Mocked/NotMocked möglich? @InterceptorBinding @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(value=RetentionPolicy.RUNTIME) @Inherited public@interfaceCheckMockedContext{} publicinterfaceContextResolver{ @CheckMockedContext publicAnnotationLiteralresolveContext(finalClass<?>targetClass); } JAVA
  • 74. @SvenRuppert 76/122 CDI explained by code 3a / 6 ContextResolver @Interceptor@CheckMockedContext publicclassMockedInterceptorimplementsSerializable{ @InjectCDIContextcontext; private@Inject@CDILoggerLoggerlogger; @AroundInvoke publicObjectcheckMockedMode(InvocationContextctx)throwsException{ if(context.isMockedModusActive()){ if(logger.isDebugEnabled()){logger.debug("MockedModusactive");} returnnewAnnotationLiteral<CDICommonsMocked>(){}; }else{ returnctx.proceed(); } } } JAVA
  • 75. @SvenRuppert 77/122 CDI explained by code 3b / 6 ContextResolver Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar
  • 76. @SvenRuppert 78/122 CDI explained by code 3b / 6 ContextResolver Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar Benötigt wird aber evtl differenziertes Umschalten.
  • 77. @SvenRuppert 79/122 CDI explained by code 3b / 6 ContextResolver Durch Interzeptoren meist nur allgemeine Umschaltlogik darstellbar Benötigt wird aber evtl differenziertes Umschalten. Interzeptoren werden statisch definiert - schade....
  • 78. @SvenRuppert 80/122 CDI explained by code 4a / 6 ContextResolver @CDICommons public class DefaultContextResolver implements ContextResolver { @Inject @CDILogger Logger logger; @Inject BeanManager beanManager; public Set<ContextResolver> gettAllContextResolver() { final Set<ContextResolver> resultSet = new HashSet<>(); final Set<Bean<?>> allBeans = beanManager .getBeans(ContextResolver.class, new AnnotationLiteral<Any>() {}); allBeans.forEach(b-> b.getTypes().stream() .filter(t -> t.equals(ContextResolver.class)) .filter(r -> !r.getClass().isAnnotationPresent(CDICommonsMocked.class)) .forEach(t -> { final ContextResolver cr = ((Bean<ContextResolver>) b) .create(beanManager.createCreationalContext((Bean<ContextResolver>) b)); resultSet.add(cr); })); return resultSet; } JAVA
  • 79. @SvenRuppert 81/122 CDI explained by code 4b / 6 ContextResolver publicSet<ContextResolver>gettAllMockedContextResolver(){ finalSet<ContextResolver>resultSet=newHashSet<>(); finalSet<Bean<?>>allBeans=beanManager .getBeans(ContextResolver.class,newAnnotationLiteral<CDICommonsMocked>(){}); allBeans.forEach(b->b.getTypes().forEach(type->{ if(type.equals(ContextResolver.class)){ finalContextResolvert=((Bean<ContextResolver>)b) .create(beanManager.createCreationalContext((Bean<ContextResolver>)b)); resultSet.add(t); } })); returnresultSet; } JAVA
  • 80. @SvenRuppert 82/122 CDI explained by code 4c / 6 ContextResolver publicAnnotationLiteralresolveContext(ClasstargetClass){ Stream<ContextResolver>contextResolversMocked=gettAllMockedContextResolver().stream(); Stream<ContextResolver>contextResolvers=gettAllContextResolver().stream(); returncontextResolversMocked .filter(r->(r.resolveContext(targetClass)!=null)) .map(r->r.resolveContext(targetClass)) .findFirst().orElse( contextResolvers .filter(r->!r.getClass().isAnnotationPresent(CDICommonsMocked.class)) .filter(r->!r.getClass().equals(DefaultContextResolver.class)) .filter(r->(r.resolveContext(targetClass)!=null)) .map(r->r.resolveContext(targetClass)) .findFirst().orElse(null) ); } JAVA
  • 81. @SvenRuppert 83/122 CDI explained by code 5 / 6 ContextResolver @Singleton publicclassTestContextimplementsCDIContext{ privatebooleantestModus=false; @OverridepublicbooleanisMockedModusActive(){returntestModus;} publicbooleanisTestModus(){returntestModus;} publicvoidsetTestModus(booleantestModus){this.testModus=testModus;} } publicclassTestContextResolverimplementsContextResolver{ @InjectCDIContextcontext; @CheckMockedContext @OverridepublicAnnotationLiteralresolveContext(Class<?>targetClass){ //entscheideobDuzuständigbist returnnewAnnotationLiteral<CDICommons>(){}; } } JAVA
  • 82. @SvenRuppert 84/122 CDI explained by code 6 / 6 ContextResolver Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren.
  • 83. @SvenRuppert 85/122 CDI explained by code 6 / 6 ContextResolver Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren. ContextResolver sind immer nur in ihrem fachlichen Bereich aktiv
  • 84. @SvenRuppert 86/122 CDI explained by code 6 / 6 ContextResolver Wir sind nun in der Lage dynamisch auf den Systemzustand zu reagieren. ContextResolver sind immer nur in ihrem fachlichen Bereich aktiv Unterscheidung auf z.B. Mandantenebene leicht realisierbar
  • 85. @SvenRuppert 87/122 CDI explained by code 1 / 7 CDI managed DynamicObjectAdapter - besserer Decorator klassischer Decorator in CDI @Decorator publicabstractclassCoderDecoratorimplementsCoder{ @Inject@Delegate@AnyCodercoder; publicStringcodeString(Strings,inttval){ intlen=s.length(); return"""+s+""becomes"+"""+coder.codeString(s,tval) +"","+len+"charactersinlength"; } } Insidebeans.xml <decorators> <class>decorators.CoderDecorator</class> </decorators> JAVA
  • 86. @SvenRuppert 88/122 CDI explained by code 2 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Ein Decorator in CDI muss in der beans.xml definiert werden.
  • 87. @SvenRuppert 89/122 CDI explained by code 2 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Ein Decorator in CDI muss in der beans.xml definiert werden. Klasse mit einer speziellen Annotation @Decorator
  • 88. @SvenRuppert 90/122 CDI explained by code 2 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Ein Decorator in CDI muss in der beans.xml definiert werden. Klasse mit einer speziellen Annotation @Decorator Innerhalb des Decorators muss die Instanz des Originals injiziert werden
  • 89. @SvenRuppert 91/122 CDI explained by code 2 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Ein Decorator in CDI muss in der beans.xml definiert werden. Klasse mit einer speziellen Annotation @Decorator Innerhalb des Decorators muss die Instanz des Originals injiziert werden Decorator muss von der Original-Implementierung oder dem Interface ableiten
  • 90. @SvenRuppert 92/122 CDI explained by code 2 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Ein Decorator in CDI muss in der beans.xml definiert werden. Klasse mit einer speziellen Annotation @Decorator Innerhalb des Decorators muss die Instanz des Originals injiziert werden Decorator muss von der Original-Implementierung oder dem Interface ableiten ... geht das auch schöner ?
  • 91. @SvenRuppert 93/122 CDI explained by code 3 / 7 CDI managed DynamicObjectAdapter - der bessere Decorator Aus der Sicht des Entwicklers @CDINotMapped publicinterfaceDemoLogic{ publicdefaultintadd(inta,intb){ returna+b;} publicdefaultintsub(inta,intb){ returna-b;} } @CDINotMapped publicclassDemoLogicAdapter_AimplementsDemoLogic{ publicintadd(inta,intb){ returna+b+100; } } @Singleton //sollteschonbekanntsein;-) publicclassContext{publicbooleanoriginal=true;} JAVA
  • 92. @SvenRuppert 94/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic
  • 93. @SvenRuppert 95/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic
  • 94. @SvenRuppert 96/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1)
  • 95. @SvenRuppert 97/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2.
  • 96. @SvenRuppert 98/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2. Context-Switch auf mandantenabhängige Implementierung
  • 97. @SvenRuppert 99/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2. Context-Switch auf mandantenabhängige Implementierung Holen einer Instanz der DemoLogic
  • 98. @SvenRuppert 100/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2. Context-Switch auf mandantenabhängige Implementierung Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1)
  • 99. @SvenRuppert 101/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2. Context-Switch auf mandantenabhängige Implementierung Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 102.
  • 100. @SvenRuppert 102/122 CDI explained by code 4a / 7 CDI managed DynamicObjectAdapter - besserer Decorator Injizieren der Referenz auf DemoLogic Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 2. Context-Switch auf mandantenabhängige Implementierung Holen einer Instanz der DemoLogic Aufruf der Methode add(1,1) Überprüfung ob das Ergebnis den Erwartungen entspricht, hier der Wert 102. Kaffee trinken.
  • 101. @SvenRuppert 103/122 CDI explained by code 4b / 7 CDI managed DynamicObjectAdapter - besserer Decorator @Inject@DynamicDecoratorTestInstance<DemoLogic>demoLogic; @InjectContextcontext; @Test publicvoidtestDemoLogicOriginalTest()throwsException{ Assert.assertNotNull(demoLogic); finalDemoLogicdemoLogic1=demoLogic.get(); finalintadd=demoLogic1.add(1,1); Assert.assertEquals(2,add); System.out.println("add="+add); context.original=false; finalDemoLogicdemoLogic2=demoLogic.get(); finalintaddAdapted=demoLogic2.add(1,1); Assert.assertEquals(102,addAdapted); System.out.println("addAdapted="+addAdapted); } JAVA
  • 102. @SvenRuppert 104/122 CDI explained by code 4c / 7 CDI managed DynamicObjectAdapter - besserer Decorator manuelles aktivieren von CDI.. yepp das geht public<T>TactivateCDI(Tt){ finalClassaClass=t.getClass(); if(logger.isDebugEnabled()){logger.debug("activateCDI->"+aClass);} AnnotatedTypeannotationType=beanManager.createAnnotatedType(aClass); InjectionTargetinjectionTarget=beanManager.createInjectionTarget(annotationType); CreationalContextcreationalContext=beanManager.createCreationalContext(null); injectionTarget.inject(t,creationalContext); injectionTarget.postConstruct(t); returnt; } JAVA
  • 103. @SvenRuppert 105/122 CDI explained by code 5 / 7 CDI managed DynamicObjectAdapter - besserer Decorator public class DemoLogicProducer { @Inject Instance<DynamicObjectAdapterFactory> dOAFInstance; @Inject Context context; @Produces @DynamicDecoratorTest public DemoLogic create(ManagedInstanceCreator instanceCreator){ final DemoLogic demoLogic = instanceCreator.activateCDI(new DemoLogic() {}); final DynamicObjectAdapterFactory dynamicObjectAdapterFactory = dOAFInstance.get(); final Object adapter; if (context.original){ adapter = new Object(); } else { //kann hier beliebig komplex werden adapter = instanceCreator.activateCDI(new DemoLogicAdapter_A()); } //hier interface notwendig... see insight return dynamicObjectAdapterFactory.adapt(demoLogic, DemoLogic.class, adapter); } JAVA
  • 104. @SvenRuppert 106/122 CDI explained by code 6 / 7 CDI managed DynamicObjectAdapter - besserer Decorator publicclassDynamicObjectAdapterFactory{ @InjectInstance<CDIInvocationHandler>cdiInvocationHandlerInstance; public<T>Tadapt(finalObjectadaptee,finalClass<T>target,finalObjectadapter){ finalCDIInvocationHandlerinvocationHandler= cdiInvocationHandlerInstance.get().adapter(adapter).adaptee(adaptee); return(T)Proxy.newProxyInstance( target.getClassLoader(), newClass[]{target}, //hierInterfacenotwendig! invocationHandler ); } } JAVA
  • 105. @SvenRuppert 107/122 CDI explained by code 7a / 7c CDI managed DynamicObjectAdapter - besserer Decorator publicclassMethodIdentifier{ privatefinalStringname; privatefinalClass[]parameters; publicMethodIdentifier(Methodm){ name=m.getName();parameters=m.getParameterTypes(); } //wecansavetimebyassumingthatweonlycompareagainst //otherMethodIdentifierobjects publicbooleanequals(Objecto){ MethodIdentifiermid=(MethodIdentifier)o; returnname.equals(mid.name)&&Arrays.equals(parameters,mid.parameters); } publicinthashCode(){ returnname.hashCode();} } JAVA
  • 106. @SvenRuppert 108/122 CDI explained by code 7b / 7c CDI managed DynamicObjectAdapter - besserer Decorator publicclassCDIInvocationHandlerimplementsInvocationHandler{ privateMap<MethodIdentifier,Method>adaptedMethods=newHashMap<>(); privateObjectadapter;privateObjectadaptee; publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ if(adaptedMethods.isEmpty()){ Method[]methods=adapter.getClass().getDeclaredMethods(); for(Methodm:methods){ adaptedMethods.put(newMethodIdentifier(m),m);} } try{ Methodother=adaptedMethods.get(newMethodIdentifier(method)); if(other!=null) {returnother.invoke(adapter,args);} else {returnmethod.invoke(adaptee,args); } }catch(InvocationTargetExceptione){throwe.getTargetException();} }... JAVA
  • 107. @SvenRuppert 109/122 CDI explained by code 7c / 7c CDI managed DynamicObjectAdapter - besserer Decorator Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI Decorators auszugleichen.
  • 108. @SvenRuppert 110/122 CDI explained by code 7c / 7c CDI managed DynamicObjectAdapter - besserer Decorator Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI Decorators auszugleichen. Spätere Änderungen an dem Interface führen nicht dazu, dass alle Adapter angepasst werden müssen
  • 109. @SvenRuppert 111/122 CDI explained by code 7c / 7c CDI managed DynamicObjectAdapter - besserer Decorator Mit diesem Pattern sind wir in der Lage die Unzulänglichkeiten des CDI Decorators auszugleichen. Spätere Änderungen an dem Interface führen nicht dazu, dass alle Adapter angepasst werden müssen Alle Komponenten sind von dem verwendeten CDI-Container verwaltet
  • 110. @SvenRuppert 112/122 Cross Language Injection .. am Beispiel von Kotlin.. classDemoLogicKotlin(){ publicfunworkOnString():String{ return"DemoLogicKotlin" } } JAVA
  • 111. @SvenRuppert 113/122 Cross Language Injection .. am Beispiel von Kotlin.. entweder : Adapter mit Delegator @CDINotMapped publicclassDemoLogicKotlinWrapperimplementsDemoLogic{ private@InjectDemoLogicKotlinkotlin; publicStringworkOnString(){ returnkotlin.workOnString(); } } JAVA
  • 112. @SvenRuppert 114/122 Cross Language Injection .. am Beispiel von Kotlin.. oder mittels Producer direkt verfügbar machen @CDINotMapped publicclassDemoLogicKotlinProducer{ @InjectManagedInstanceCreatorcreator; //@InjectDemoLogicKotlinkotlin; @Produces@KotlinImpl publicDemoLogiccreate(){ finalDemoLogiclogic=newDemoLogicKotlinWrapper(); returncreator.activateCDI(logic); } } JAVA
  • 113. @SvenRuppert 115/122 CDI und TDD ... kaskadierte MOCKS Service A injected Service B injected Service C
  • 114. @SvenRuppert 116/122 CDI und TDD ... kaskadierte MOCKS Service A injected Service B injected Service C Service A (mocked) injected Service B injected Service C
  • 115. @SvenRuppert 117/122 CDI und TDD ... kaskadierte MOCKS Service A injected Service B injected Service C Service A (mocked) injected Service B injected Service C Service A injected Service B (mocked) injected Service C
  • 116. @SvenRuppert 118/122 CDI und TDD ... kaskadierte MOCKS Service A injected Service B injected Service C Service A (mocked) injected Service B injected Service C Service A injected Service B (mocked) injected Service C Service A (mocked) injected Service B (mocked) injected Service C
  • 117. @SvenRuppert 119/122 CDI und TDD ... kaskadierte MOCKS Service A injected Service B injected Service C Service A (mocked) injected Service B injected Service C Service A injected Service B (mocked) injected Service C Service A (mocked) injected Service B (mocked) injected Service C beliebige Kombinationen können so dynamisch zusammen geschaltet werden.
  • 118. @SvenRuppert 120/122 finally at amazon.. my book with Dr, Heinz Kabutz Book about Reflection - part one Dynamic Proxies z.B. ...dynamic static proxies... ;-)
  • 119. <Thank You!> g+ www.google.com/+SvenRuppert twitter @SvenRuppert www www.rapidpm.org