Jakarta CDI - Lab 1 - Basic part 2
In this lab, we will explore using CDI qualifiers to work when there are several implementations of a single interface.
1. Define an instrument
Steps
- Open the
01-jakarta-eeproject and navigate to thesrc/main/java - Create an
interfacecalledInstrumentin theexpert.os.labs.persistence.cid.musicpackage - Add a
sound()method that returnsString
Expected results
- Interface
Instrumentthat will produce asound()for the later instrument types
Solution
2. Define the instrument types
Steps
- Create an
enumcalledInstrumentTypein theexpert.os.labs.persistence.cid.musicpackage - Add the following constants, related to the different musical instrument types:
STRINGPERCUSSIONKEYBOARD
Expected results
- Enum
InstrumentTypecreated in thesrc/main/javaat theexpert.os.labs.persistence.cdi.music
Solution
3. Create a custom Qualifier Annotation (the musical instruments)
The annotated class will represent musical instruments and specify the instrument type.
Steps
- Create an
@interfacecalledMusicalInstrumentin theexpert.os.labs.persistence.cid.musicpackage -
Add the following code:
import jakarta.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @interface MusicalInstrument { InstrumentType value(); } -
Define different musical instruments (classes), implementing the
Instrumentinterface:- the classes must be created at the
expert.os.labs.persistence.cid.musicpackage - use the
jakarta.enterprise.injectpackage to import the@Defaultannotation
Class Annotation sound Piano@MusicalInstrument(InstrumentType.KEYBOARD)and@Defaultreturn "piano"Violin@MusicalInstrument(InstrumentType.STRING)return "violin"Xylophone@MusicalInstrument(InstrumentType.PERCUSSION)return "xylophone" - the classes must be created at the
Expected results
- Three classes (
Piano,Violin, andXylophone) represent different musical instruments and are annotated withMusicalInstrumentto specify their instrument types. @Defaultannotation is used on thePianoclass, indicating it as the default implementation for theInstrumentinterface.
Solution
Click to see...
Piano class
import jakarta.enterprise.inject.Default;
@MusicalInstrument(InstrumentType.KEYBOARD)
@Default
class Piano implements Instrument {
@Override
public String sound() {
return "piano";
}
}
Violin class
@MusicalInstrument(InstrumentType.STRING)
class Violin implements Instrument {
@Override
public String sound() {
return "violin";
}
}
Xylophone class
4. Create the orchestra
The Orchestra class represents an orchestra and is annotated with @ApplicationScoped, indicating that there will be a single instance of this class per application.
It contains fields for different types of musical instruments (percussion, keyboard, string, and solo) and an Instance<Instrument> to handle multiple instrument instances.
The class includes methods to play specific types of instruments (string(), percussion(), keyboard()), play a solo instrument (solo()), and play all available instruments (allSound()).
Steps
- Create a class called
Orchestrain theexpert.os.labs.persistence.cid.musicpackage - Annotate the class with
@ApplicationScopedfrom thejakarta.enterprise.contextpackage -
Add a logger for this class
-
Add the following
Instrumentfields with the related annotationsField name Annotation 1 Annotation 2 percussion@Inject@MusicalInstrument(InstrumentType.PERCUSSION)keyboard@Inject@MusicalInstrument(InstrumentType.KEYBOARD)string@Inject@MusicalInstrument(InstrumentType.STRING)solo@Inject -
Add the
Instrumentinstance as a new field as follows: -
Add the following methods, that are related to each instrument type
-
Add a method to list all sounds
Expected results
- Class
Orchestrathat can call any musical instrument to play
Solution
Click to see...
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@ApplicationScoped
public class Orchestra {
private static final Logger LOGGER = Logger.getLogger(Orchestra.class.getName());
@Inject
@MusicalInstrument(InstrumentType.PERCUSSION)
private Instrument <;
@Inject
@MusicalInstrument(InstrumentType.KEYBOARD)
private Instrument keyboard;
@Inject
@MusicalInstrument(InstrumentType.STRING)
private Instrument string;
@Inject
private Instrument solo;
@Inject
@Any
private Instance<Instrument> instruments;
public void string() {
LOGGER.info("The string's sound: " + this.string.sound());
}
public void percussion() {
LOGGER.info("The percussion's sound: " + this.percussion.sound());
}
public void keyboard() {
LOGGER.info("The keyboard's sound: " + this.keyboard.sound());
}
public void solo() {
LOGGER.info("The solo's sound: " + this.keyboard.sound());
}
public void allSound() {
String sounds = this.instruments.stream().map(Instrument::sound).collect(Collectors.joining(", "));
LOGGER.info("All instruments sounds are: " + sounds);
}
}
5. Explore the class usage
Steps
- Create a class called
AppOrchestrain theexpert.os.labs.persistence.cidpackage -
Add the following code to the class
import expert.os.labs.persistence.persistence.cdi.music.Orchestra; import jakarta.enterprise.inject.se.SeContainer; import jakarta.enterprise.inject.se.SeContainerInitializer; public class App2 { public static void main(String[] args) { try (SeContainer container = SeContainerInitializer.newInstance().initialize()) { Orchestra orchestra = container.select(Orchestra.class).get(); orchestra.percussion(); orchestra.keyboard(); orchestra.string(); orchestra.solo(); orchestra.allSound(); } } } -
Run the class
Expected results
-
List of
INFOmessages related to each instrument called by the Orchestra
Solution
Click to see...
import expert.os.labs.persistence.persistence.cdi.music.Orchestra;
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
public class AppOrchestra {
public static void main(String[] args) {
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
Orchestra orchestra = container.select(Orchestra.class).get();
orchestra.percussion();
orchestra.keyboard();
orchestra.string();
orchestra.solo();
orchestra.allSound();
}
}
}