2/3 : cdi advanced - antoine sabot-durand
DESCRIPTION
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.TRANSCRIPT
CDI ADVANCEDMeta Data & Extensions
@antoine_sd
ANTOINE SABOT-DURAND
• Senior Software Engineer @Red Hat
• Java & OSS :
• CDI co-spec lead
• CDI community development
• Tech Lead on Agorava
• @antoine_sd
MEET CDI SPI
SPI CAN BE SPLIT IN 4 PARTS
1.SPI DEDICATED TO TYPE META-MODEL
WHY HAVING A TYPE META-MODEL?
WHY HAVING A TYPE META-MODEL?Because @Annotations are configuration
WHY HAVING A TYPE META-MODEL?Because @Annotations are configuration
but they are also read-only
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
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
2.SPI DEDICATED TO CDI META-MODEL
SPI CAN BE USED IN YOUR CODE 1
@Producespublic <K, V> Map<K, V> produceMap(InjectionPoint ip) { if (valueIsNumber(ip.getType())) { return new TreeMap<K, V>(); } return new HashMap<K, V>();}
SPI CAN BE USED IN YOUR CODE 2public 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"); } }
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"); } }
3. CDI ENTRY POINTS
SPI DEDICATED TO EXTENSIONS
MOST OF THESE SPI ARE EVENTS CONTAINING META MODEL SPI CLASSES
MOST OF THESE SPI ARE EVENTS CONTAINING META MODEL SPI CLASSES
ProcessAnnotatedType
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
CDI EXTENSIONS
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
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
CDI 1.1 LIFECYCLE
Before Bean Discovery
Process BeanProcess Annotated
Type
ScanArchive
ApplicationRunning
After Deployment Validation
Before Shutdown Undeploy ApplicationProcess Producer
After Bean Discovery
ProcessInjection Target
Process Observer Method
ProcessInjection Point
Process Bean Attributes
After Type Discovery
Occurs once
occurs for each elts
internal step
Deployment starts
Bean eligibility check
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
SIMPLE EXAMPLE - VETO JPA ENTITIES
public class VetoEntityExtension implements Extension { void vetoEntites(@Observes @WithAnnotations(Entity.class)ProcessAnnotatedType<?> pat) { pat.veto(); }}
QUESTIONS