CDI Basics and Selection

Back

Loading concept...

🏭 CDI: The Magic Factory That Builds Your Objects

The Big Picture: What is CDI?

Imagine you’re building with LEGO blocks. Instead of finding each piece yourself, what if a magic helper brought you exactly the pieces you need, already connected? That’s what CDI (Contexts and Dependency Injection) does in Jakarta EE!

CDI is like a super-smart assistant that:

  • Creates objects for you automatically
  • Connects them together
  • Makes sure everyone gets the right helper

🫘 CDI Beans: The Building Blocks

What is a CDI Bean?

A CDI Bean is simply a Java class that CDI can manage. Think of beans like employees in a company. Each employee has a job, and the company (CDI) knows who they are and what they do.

Any regular class can become a CDI Bean!

public class CoffeeMachine {
    public String makeCoffee() {
        return "Here's your coffee! ☕";
    }
}

That’s it! This class is automatically a CDI Bean. CDI sees it and says: “I can manage this!”

What Makes a Good Bean?

A CDI Bean needs:

  1. A no-argument constructor (or one CDI understands)
  2. Not be final (CDI needs to extend it sometimes)
  3. Be a concrete class (not abstract or interface)
// ✅ This is a valid CDI Bean
public class OrderService {
    public void placeOrder() {
        System.out.println("Order placed!");
    }
}

// ❌ This won't work (no concrete class)
public abstract class AbstractService { }

🔍 Bean Discovery Modes: How CDI Finds Your Beans

CDI needs to know which classes to manage. This is called discovery. Think of it like a teacher taking attendance:

graph TD A["Bean Discovery Mode"] --> B["all"] A --> C["annotated"] A --> D["none"] B --> E["Every class is a bean"] C --> F["Only marked classes are beans"] D --> G["CDI is turned off"]

The Three Modes

Mode What It Does Think of It As
all Every class becomes a bean “Everyone’s invited!”
annotated Only classes with special marks “VIP list only”
none No beans at all “Party canceled”

Example: The “annotated” mode needs marks like this:

@ApplicationScoped  // This mark says "I'm a bean!"
public class UserService {
    public String getUser() {
        return "John";
    }
}

📄 beans.xml: The Rule Book

The beans.xml file tells CDI how to behave. It lives in the META-INF or WEB-INF folder.

Minimal beans.xml (Recommended)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
       version="4.0"
       bean-discovery-mode="annotated">
</beans>

What Each Part Means

graph TD A["beans.xml"] --> B["version"] A --> C["bean-discovery-mode"] B --> D["Which CDI version?"] C --> E["all / annotated / none"]

Quick Guide:

  • annotated = Only beans with scope annotations (safest, fastest)
  • all = Everything is a bean (slower, but easy)
  • none = CDI doesn’t work here

💉 CDI Injection Points: Where the Magic Happens

Injection is when CDI automatically gives you an object you need. Instead of creating objects yourself, you just ask for them!

The Old Way (Without CDI) 😓

public class OrderController {
    private OrderService service;

    public OrderController() {
        // You have to create it yourself!
        this.service = new OrderService();
    }
}

The CDI Way (With Injection) 🎉

public class OrderController {
    @Inject
    private OrderService service;
    // CDI creates and gives you the service!
}

Three Ways to Inject

graph TD A["Injection Points"] --> B["Field Injection"] A --> C["Constructor Injection"] A --> D["Setter Injection"] B --> E["@Inject on field"] C --> F["@Inject on constructor"] D --> G["@Inject on setter method"]

1. Field Injection (Most common)

@Inject
private PaymentService paymentService;

2. Constructor Injection (Best practice)

private final OrderService orderService;

@Inject
public OrderController(OrderService orderService) {
    this.orderService = orderService;
}

3. Setter Injection

private NotificationService notifier;

@Inject
public void setNotifier(NotificationService n) {
    this.notifier = n;
}

🏷️ CDI Qualifiers: Name Tags for Beans

What if you have two classes that do similar things? How does CDI know which one to use?

Qualifiers are like name tags that tell CDI exactly which bean you want!

The Problem

public interface PaymentProcessor { }

public class CreditCardProcessor
    implements PaymentProcessor { }

public class PayPalProcessor
    implements PaymentProcessor { }

// CDI is confused! Which one do you want?
@Inject
private PaymentProcessor processor; // ❌ Error!

The Solution: Create a Qualifier

// Step 1: Create name tags
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface CreditCard { }

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface PayPal { }
// Step 2: Put name tags on beans
@CreditCard
public class CreditCardProcessor
    implements PaymentProcessor { }

@PayPal
public class PayPalProcessor
    implements PaymentProcessor { }
// Step 3: Ask for the specific one
@Inject @CreditCard
private PaymentProcessor processor; // ✅ Works!

Built-in Qualifiers

CDI gives you some qualifiers for free:

Qualifier What It Means
@Default The normal choice
@Any Matches everything
@Named Give it a string name
@Inject @Named("fastShipping")
private ShippingService shipping;

🔄 CDI Alternatives: Swapping Beans Like Costumes

Alternatives let you swap one bean for another without changing your code. Perfect for:

  • Testing (use a fake database)
  • Different environments (dev vs production)
  • Feature flags

How It Works

graph TD A["Normal Bean"] --> B["Used by default"] C["Alternative Bean"] --> D["Disabled by default"] E["Enable in beans.xml"] --> F["Alternative replaces Normal!"]

Step 1: Mark the Alternative

// The normal bean
public class RealEmailService {
    public void send(String msg) {
        // Actually sends email
    }
}

// The alternative for testing
@Alternative
public class MockEmailService {
    public void send(String msg) {
        System.out.println("FAKE: " + msg);
    }
}

Step 2: Enable in beans.xml

<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
       version="4.0"
       bean-discovery-mode="annotated">
    <alternatives>
        <class>com.app.MockEmailService</class>
    </alternatives>
</beans>

Now MockEmailService replaces RealEmailService everywhere!

Priority Alternative (No XML Needed!)

@Alternative
@Priority(100)
public class MockEmailService {
    // This automatically wins!
}

Higher priority number = more important = gets chosen!


🎯 Putting It All Together

Here’s how everything connects:

graph TD A["Your Code"] --> B["Asks for a Bean"] B --> C{CDI Container} C --> D["Checks Qualifiers"] C --> E["Checks Alternatives"] C --> F["Checks Discovery Mode"] D --> G["Injects Right Bean"] E --> G F --> G G --> H["Your Code Works!"]

Complete Example

// 1. The interface
public interface MessageSender {
    void send(String message);
}

// 2. Email implementation
@Email  // Custom qualifier
@ApplicationScoped
public class EmailSender implements MessageSender {
    public void send(String message) {
        System.out.println("📧 " + message);
    }
}

// 3. SMS implementation
@SMS  // Custom qualifier
@ApplicationScoped
public class SmsSender implements MessageSender {
    public void send(String message) {
        System.out.println("📱 " + message);
    }
}

// 4. Using them
@ApplicationScoped
public class NotificationService {

    @Inject @Email
    private MessageSender emailer;

    @Inject @SMS
    private MessageSender texter;

    public void notifyAll(String msg) {
        emailer.send(msg);
        texter.send(msg);
    }
}

🚀 Quick Recap

Concept One-Line Summary
CDI Bean Any class CDI manages for you
Discovery Mode How CDI finds beans (all/annotated/none)
beans.xml Configuration file for CDI rules
Injection CDI gives you objects automatically
Qualifiers Name tags when multiple beans exist
Alternatives Swap beans without code changes

Remember: CDI is your helpful assistant. You define what you need, and CDI delivers it—automatically, reliably, and magically! ✨

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.