Allez plus Loin avec CDI
En moins de 5 ans d’existence, Contexts and Dependency Injection (CDI) est devenue l’une des principale spécification de Java EE. Néanmoins, CDI est bien souvent perçu comme une simple solution d’injection de dépendance enrichie alors que cette spécification est bien plus riche que ça. Lors de cette présentation, après un rapide rappel des fonctionnalités de base de CDI, nous montrerons comment son utilisation avancée permet Java EE en intégrant des technologies legacy ou plus récent de manière naturelle. Nous finirons avec le travail en cours sur CDI 2.0 qui a commencé début septembre.
2. ANTOINE SABOT-DURAND
• Senior Software Engineer @Red Hat
• Java & OSS :
• CDI co-spec lead
• CDI community development
• Tech Lead on Agorava
• @antoine_sd
7. WHY HAVING A TYPE META-MODEL?
Because @Annotations are configuration
8. WHY HAVING A TYPE META-MODEL?
Because @Annotations are configuration
but they are also read- only
9. WHY HAVING A TYPE META-MODEL?
Because @Annotations are configuration
but they are also read- only
as we want to write configuration
We need a mutable meta-model
10. WHY HAVING A TYPE META-MODEL?
Because @Annotations are configuration
but they are also read- only
as we want to write configuration
We need a mutable meta-model
for annotated types
12. SPI CAN BE USED IN YOUR CODE 1
@Produces
public <K, V> Map<K, V> produceMap(InjectionPoint ip) {
if (valueIsNumber(ip.getType())) {
return new TreeMap<K, V>();
}
return new HashMap<K, V>();
}
13. SPI CAN BE USED IN YOUR CODE 2
public abstract class AbstractBean {
@Inject
Bean<AbstractBean> meta;
@Inject
Instance<Foo> fooInstances;
public Foo getFooWithSameQualifiers()
{
Annotation[] beanQualifiers = (Annotation[]) meta.getQualifiers().toArray();
Instance<Foo> mySelect = fooInstances.select(beanQualifiers);
if (!(mySelect.isUnsatisfied() && mySelect.isAmbiguous()))
return mySelect.get();
else
throw new IllegalStateException("Foo with same qualifiers not found");
}
}
14. SPI CAN BE USED IN YOUR CODE 3
@ApplicationScoped
public class ExampleBean {
private void strictListen(@Observes @Qualified Payload evt, EventMetadata meta)
{
if(meta.getQualifiers().contains(new QualifiedLiteral())
&& meta.getType().equals(Payload.class))
System.out.println("Do something");
else
System.out.println("ignore");
}
}
17. MOST OF THESE SPI ARE EVENTS
CONTAINING META MODEL SPI CLASSES
18. MOST OF THESE SPI ARE EVENTS
CONTAINING META MODEL SPI CLASSES
ProcessAnnotatedType
19. MOST OF THESE SPI ARE EVENTS
CONTAINING META MODEL SPI CLASSES
These Events are automatically fired by CDI
when application starts and can observed
in method included in a CDI extension
21. CDI EXTENSIONS FOR WHAT ?
• A CDI extension can :
• Create / modify :
• Beans
• Injection Target
• Injection Points
• Cancel beans creation
• More generally extensions can modify all CDI
context at launch time
22. TO UNDERSTAND EXTENSIONS
• Once application is bootstrapped, the
Bean Manager is in read only mode (no
dynamic bean registration)
• Extensions are launch during bootsrap
and are based on CDI events
• You only have to @Observes built-in
CDI event to create your extensions
• Learn the different events fired at boot
time on next slide
23. CDI 1.1 LIFECYCLE
Before Bean
Discovery
Process Bean
Scan
Archive
Process Annotated
Type
After Deployment
Validation
Application
Running
After Bean
Discovery
Process Producer Before Shutdown Undeploy Application
Process
Injection Target
Process Observer
Method
Process
Injection Point
Process Bean
Attributes
After Type Discovery
Occurs once
occurs for each elts
internal step
Deployment starts
Bean eligibility check
24. HOW TO BUILD A CDI EXTENSION
• Create a class implementing
javax.enterprise.inject.spi.Extension
• Add some method that observes CDI lifecyle
events to modify Bean Manager meta data
• Add file :
META-INF/services/
javax.enterprise.inject.spi.Extension
in class path. And put the qualified name of the
extension in it
25. SIMPLE EXAMPLE - VETO JPA ENTITIES
public class VetoEntityExtension implements Extension {
void vetoEntites(@Observes @WithAnnotations(Entity.class)ProcessAnnotatedType<?> pat) {
pat.veto();
}
}