DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Understanding Jakarta EE 8 CDI (Part 2): Qualifying Your Beans
  • Functional Endpoints: Alternative to Controllers in WebFlux
  • Spring, IoC Containers, and Static Code: Design Principles
  • Making Readable Code With Dependency Injection and Jakarta CDI

Trending

  • Understanding and Mitigating IP Spoofing Attacks
  • Performance Optimization Techniques for Snowflake on AWS
  • Build an MCP Server Using Go to Connect AI Agents With Databases
  • Teradata Performance and Skew Prevention Tips
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Understanding Jakarta EE 8 - CDI Part 1

Understanding Jakarta EE 8 - CDI Part 1

By 
BUHAKE SINDI user avatar
BUHAKE SINDI
DZone Core CORE ·
Updated Jul. 23, 20 · Tutorial
Likes (13)
Comment
Save
Tweet
Share
16.7K Views

Join the DZone community and get the full member experience.

Join For Free

The fundamental purpose of a software developer is to write code that is:

  • Easily maintainable and testable.
  • Loosely Coupled.
  • Easily extensible.

Building a distributed Java enterprise application required huge understanding in wiring various mainstream technologies across various application tiers, tying web controllers to database backend through a series of application and business services. This made it difficult to achieve the points highlighted above, making it a huge learning curve for developers to do what they do best: to write code.

Context and Dependency Injection (C.D.I) is one such technology that was introduced in Java EE 6 (JSR 299), with the goal to help knit the web tier with the transactional tier.

The Jakarta EE 8 CDI specification version is CDI 2.0, which is an update to CDI 1.2 (JSR 346).

Dependency Injection

According to Wikipedia:

In software engineering, dependency injection is a technique in which
an object receives other objects that it depends on. These other
objects are called dependencies. In the typical “using” relationship
the receiving object is called a client and the passed (that is,
“injected”) object is called a service.

Dependency Injection helps eliminate the need of hard-coding dependencies (object creation and instantiation), thus making our application loosely coupled, maintanable, extendable, and easier to test. With CDI, dependency resolution is done on runtime. The DI container (the injector) is responsible for injecting dependent beans.

So, What Is C.D.I.?

CDI is a type-safe approach to Dependency Injection. Among various services and features, it provides lifecycle management of stateful beans bound to well defined contexts. This allows developers a great deal of flexibility to integrate various kinds of components in a loosely coupled and type-safe way.

This article discusses dependency injection in a tutorial format. It covers some of the features of CDI such as type safe annotations configuration, alternatives and more.

Dependency Injection with CDI

To use CDI to manage bean injection, we will need to do the following:

Setting up Bean archive.

Bean classes must exists in a bean archive in order to be discoverable by the CDI container.

To enable bean archive, beans.xml must exist in the following folder, with bean-discovery-mode set to all or annotated. If the bean discovery mode is set to none, it’s no longer a bean archive file.

An example of beans.xml file, version 2.0

XML
 




xxxxxxxxxx
1


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
3
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd "
5
    version="2.0" bean-discovery-mode="all">
6
    
7
</beans>



  • In a WAR file, place your beans.xml inside WEB-INF folder.
  • In a JAR file, place your beans.xml inside the META-INF folder. In a Maven project, this file must exist inside src/main/resources/META-INF directory.

The default bean discovery mode is annotated, if version number is specified (1.1 or later), else all otherwise. This mean that all bean classes must be annotated with Bean defining annotations in order to be qualified for bean discovery.

Note: The beans.xml file can be an empty file.

Now, let’s look at various examples on how we can create bean qualified for injection. This tutorial covers the basis of dependency injection, @Inject, @Produces and @Qualifiers.

CDI in Action

In order to understand CDI we’ll have to bootstrap CDI in Java SE. Even though JSR 299 provides a requirements to implement our own CDI container, we will use existing JSR 299 Reference Implementation (RI). In this example, we use JBoss Weld, a JSR 299 CDI RI.

We include weld-se-core dependency to your Maven project.

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
    <groupId>org.jboss.weld.se</groupId>
3
    <artifactId>weld-se-core</artifactId>
4
    <version>${org.jboss.weld.se.core.version}</version>
5
</dependency>



Where org.jboss.weld.se.core.version is 3.1.4.Final at the time of writing.

We, also, don’t want Weld specific beans to be discovered by the container, so we add the following exclusion on beans.xml:

XML
 




xxxxxxxxxx
1


 
1
<scan>
2
    <exclude name="org.jboss.weld.**" />
3
</scan>



Example of Basic Dependency Injection in CDI

In this example, we will introduce basic injection by just injecting with @Inject a basic bean.

DefaultService.java

Java
 




xxxxxxxxxx
1


 
1
public class DefaultService {
2
 
          
3
    public void doWork() {
4
        System.out.println("Default Service work.");
5
    }
6
}


MainController.java

Java
 




xxxxxxxxxx
1


 
1
public class MainController {
2
 
          
3
    @Inject
4
    private DefaultService service;
5
    
6
    public void execute() {
7
        service.doWork();
8
    }
9
}


Main.java

Java
 




xxxxxxxxxx
1
19


 
1
public class Main {
2
 
          
3
    public static void main(String[] args) {
4
        SeContainer container = null;
5
        
6
        try {
7
            SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
8
            container = containerInitializer.initialize();
9
            
10
            //Get bean via CDI
11
            MainController controller = container.select(MainController.class).get();
12
            controller.execute();
13
        } finally {
14
            if (container != null) {
15
                container.close();
16
            }
17
        }
18
    }
19
}



By selecting the MainController from the container the CDI container resolve the bean in a type-safe way at runtime and inject it.

You’ll notice that DefaultService and the MainController has not been annotated by any qualified Bean annotation, so the bean is qualified as the @Default qualifier. Also, if no qualifier is passed to SeContainer.select() method, the @Default qualifier is assumed.

When we run the Main program, Weld will boostrap to the SeContainer and Weld becomes the CDI container to do the injection.

Output:

Jul 15, 2020 5:33:51 AM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 3.1.4 (Final)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jboss.weld.util.bytecode.ClassFileUtils$1 (file:/C:/Users/buhake.sindi/.m2/repository/org/jboss/weld/weld-core-impl/3.1.4.Final/weld-core-impl-3.1.4.Final.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of org.jboss.weld.util.bytecode.ClassFileUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Jul 15, 2020 5:33:52 AM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Jul 15, 2020 5:33:53 AM org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent
INFO: WELD-ENV-002003: Weld SE container 0b2888f8-0582-4b76-a2db-2c04514757a4 initialized
Default Service work.
Jul 15, 2020 5:33:53 AM org.jboss.weld.environment.se.WeldContainer shutdown
INFO: WELD-ENV-002001: Weld SE container 0b2888f8-0582-4b76-a2db-2c04514757a4 shut down

We can see that Default Service work. is outputted on the console.

The full source code of this example can be found on the GitHub source tree.

Let’s pause for a moment. We will carry on with other various ways of DI injection provided by the CDI framework as well as other features present in the specs (such as events, interceptors, etc.).

CDI Dependency injection Bean (software) Spring Framework

Opinions expressed by DZone contributors are their own.

Related

  • Understanding Jakarta EE 8 CDI (Part 2): Qualifying Your Beans
  • Functional Endpoints: Alternative to Controllers in WebFlux
  • Spring, IoC Containers, and Static Code: Design Principles
  • Making Readable Code With Dependency Injection and Jakarta CDI

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!