Advanced CDI: The Magical Toolbox for Smart Bean Management
The Story of the Smart Coffee Shop
Imagine you run a magical coffee shop. You already know how to make coffee (basic CDI). But now, you want to do fancy things:
- Wrap your barista’s work to add extra features (like logging every order) → Decorators
- Give your baristas special badges that bundle many powers at once → Stereotypes
- Invite magical helpers that can change how your shop works → Extensions
- Run a lighter, faster shop without all the heavy equipment → CDI Lite
Let’s explore each one!
1. CDI Decorators: Wrapping Gifts Around Your Beans
What is a Decorator?
Think of a Decorator like wrapping paper around a gift. The gift inside stays the same, but the wrapping adds something extra—like a bow or glitter!
In CDI, a Decorator wraps around a bean and adds extra behavior without changing the original bean.
Why Use Decorators?
- Add logging to every method call
- Add security checks
- Add caching
- Add timing measurements
The original bean doesn’t know it’s being wrapped!
Simple Example: The Logging Decorator
Let’s say you have a CoffeeService that makes coffee:
public interface CoffeeService {
String makeCoffee(String type);
}
Your basic implementation:
@ApplicationScoped
public class BasicCoffeeService
implements CoffeeService {
public String makeCoffee(String type) {
return "Here's your " + type;
}
}
Now, let’s create a Decorator that logs every coffee order:
@Decorator
@Priority(100)
public abstract class LoggingCoffeeDecorator
implements CoffeeService {
@Inject
@Delegate
CoffeeService delegate;
public String makeCoffee(String type) {
System.out.println("Order: " + type);
String result = delegate.makeCoffee(type);
System.out.println("Done: " + type);
return result;
}
}
Key Parts of a Decorator
graph TD A["Client calls makeCoffee"] --> B["Decorator intercepts"] B --> C["Decorator does BEFORE work"] C --> D["Calls delegate.makeCoffee"] D --> E["Original bean runs"] E --> F["Decorator does AFTER work"] F --> G["Result returned to client"]
| Annotation | Purpose |
|---|---|
@Decorator |
Marks class as a decorator |
@Delegate |
Injects the wrapped bean |
@Priority |
Sets order (lower = first) |
Decorator vs Interceptor
| Feature | Decorator | Interceptor |
|---|---|---|
| Works on | One specific interface | Any bean method |
| Knows about | Business logic | Cross-cutting concerns |
| Can access | Business methods | Generic method info |
2. CDI Stereotypes: Powerful Badges for Beans
What is a Stereotype?
Imagine you’re a superhero. Instead of explaining all your powers every time, you just show your badge that says “Superman” and everyone knows what you can do!
A Stereotype is a single annotation that bundles multiple annotations together.
Why Use Stereotypes?
- Less repetitive code
- Consistent behavior across beans
- Easy to change rules in one place
- Cleaner, more readable code
Simple Example: Creating an @Action Stereotype
Let’s say many of your beans need these three things:
@RequestScoped@Transactional@Named
Instead of writing all three every time:
// BEFORE: Repetitive!
@RequestScoped
@Transactional
@Named
public class OrderAction { }
@RequestScoped
@Transactional
@Named
public class PaymentAction { }
Create a stereotype:
@Stereotype
@RequestScoped
@Transactional
@Named
@Retention(RUNTIME)
@Target(TYPE)
public @interface Action { }
Now use it simply:
// AFTER: Clean and simple!
@Action
public class OrderAction { }
@Action
public class PaymentAction { }
Built-in Stereotype: @Model
CDI provides @Model out of the box:
// @Model is equivalent to:
@Named
@RequestScoped
@Stereotype
public @interface Model { }
How Stereotypes Work
graph TD A["@Action annotation"] --> B["CDI sees @Stereotype"] B --> C["CDI unpacks bundled annotations"] C --> D["@RequestScoped applied"] C --> E["@Transactional applied"] C --> F["@Named applied"]
Stereotype Inheritance
Stereotypes can include other stereotypes!
@Stereotype
@Action // includes another stereotype
@Logged // custom interceptor binding
public @interface AuditedAction { }
3. CDI Extensions: Magical Shop Helpers
What is a CDI Extension?
Extensions are like magical elves that wake up before your shop opens and can:
- Add new beans
- Remove beans
- Modify beans
- Add new scopes
- Change how CDI works
They’re the most powerful part of CDI!
When to Use Extensions?
- Integrate with other frameworks
- Create custom component models
- Add dynamic beans at startup
- Scan for custom annotations
How Extensions Work
graph TD A["CDI Container Starts"] --> B["Extensions Wake Up"] B --> C["BeforeBeanDiscovery"] C --> D["ProcessAnnotatedType - for each class"] D --> E["AfterBeanDiscovery"] E --> F["AfterDeploymentValidation"] F --> G["Application Ready!"]
Simple Extension Example
Let’s create an extension that finds all classes with @AutoRegister and makes them beans:
public class AutoRegisterExtension
implements Extension {
void afterBeanDiscovery(
@Observes AfterBeanDiscovery abd,
BeanManager bm) {
abd.addBean()
.types(MyService.class)
.scope(ApplicationScoped.class)
.createWith(ctx -> new MyService());
}
}
Registering an Extension
Create a file at:
META-INF/services/
jakarta.enterprise.inject.spi.Extension
Put your extension class name inside:
com.example.AutoRegisterExtension
Common Extension Events
| Event | When It Fires |
|---|---|
BeforeBeanDiscovery |
Before scanning starts |
ProcessAnnotatedType |
For each discovered class |
ProcessBean |
For each created bean |
AfterBeanDiscovery |
After all beans found |
AfterDeploymentValidation |
Final validation phase |
Extension Example: Adding a Custom Scope
public class MyExtension implements Extension {
void addScope(
@Observes BeforeBeanDiscovery bbd) {
bbd.addScope(
ThreadScoped.class,
true, // is normal scope
false // not passivating
);
}
}
4. CDI Lite: The Fast & Light Version
What is CDI Lite?
Imagine your coffee shop has TWO modes:
- Full Shop: Everything including the giant espresso machine, freezer, oven
- Express Cart: Just the essentials for quick service
CDI Lite is like the express cart—it has the essential features but skips the heavy stuff.
Why CDI Lite?
- Faster startup (great for microservices)
- Smaller memory footprint
- Compile-time processing possible
- Cloud-native friendly
CDI Lite vs CDI Full
| Feature | CDI Lite | CDI Full |
|---|---|---|
@Inject |
✅ Yes | ✅ Yes |
@ApplicationScoped |
✅ Yes | ✅ Yes |
@RequestScoped |
✅ Yes | ✅ Yes |
@Produces |
✅ Yes | ✅ Yes |
| Decorators | ❌ No | ✅ Yes |
| Interceptors | ❌ No | ✅ Yes |
@SessionScoped |
❌ No | ✅ Yes |
@ConversationScoped |
❌ No | ✅ Yes |
| Specialization | ❌ No | ✅ Yes |
| Extensions (SPI) | ❌ No | ✅ Yes |
What’s IN CDI Lite
graph LR A["CDI Lite Core"] --> B["@Inject"] A --> C["@ApplicationScoped"] A --> D["@RequestScoped"] A --> E["@Produces"] A --> F["Qualifiers"] A --> G["Alternatives"] A --> H["Events"]
What’s NOT in CDI Lite
- Decorators
- Interceptors
- Session & Conversation scopes
- Portable Extensions
- Specialization
- Passivation
Build Time Extensions
CDI Lite supports Build Time Extensions—these run when you compile, not when you start!
public class MyBuildExtension
implements BuildCompatibleExtension {
@Discovery
void discover(ScannedClasses scan) {
// Add classes at build time
scan.add("com.example.MyBean");
}
@Enhancement(types = MyService.class)
void enhance(ClassConfig config) {
// Modify at build time
config.addAnnotation(
ApplicationScoped.class
);
}
}
When to Use CDI Lite
✅ Use CDI Lite when:
- Building microservices
- Startup time matters
- Memory is limited
- Using frameworks like Quarkus
❌ Use CDI Full when:
- Need decorators or interceptors
- Need session scope
- Need portable extensions
- Building traditional apps
Putting It All Together
graph TD A["Your Bean"] --> B{What do you need?} B -->|Wrap with extra behavior| C["Use Decorator"] B -->|Bundle annotations| D["Use Stereotype"] B -->|Change CDI itself| E["Use Extension"] B -->|Fast, light startup| F["Use CDI Lite"]
Quick Reference
| Concept | One-Line Summary |
|---|---|
| Decorator | Wrap a bean to add behavior |
| Stereotype | Bundle annotations into one |
| Extension | Modify CDI at startup |
| CDI Lite | Lightweight CDI for fast apps |
Remember This!
🎁 Decorators = Gift wrapping for beans 🏷️ Stereotypes = Superhero badges bundling powers 🧙 Extensions = Magical elves customizing your shop 🏃 CDI Lite = Express cart—fast and light
Now you have the advanced tools to build powerful, flexible applications with CDI!
