Advanced CDI

Back

Loading concept...

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!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.