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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
Partner Zones AWS Cloud
by AWS Developer Relations
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
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Java
  4. Using Dependency Injection with Java EE

Using Dependency Injection with Java EE

When Java EE 6 introduced the CDI specification, Java EE finally included dependency injection horizontally. Here are some examples that show how to use CDI with some Java EE specifications.

Gustavo Gomes user avatar by
Gustavo Gomes
·
May. 03, 16 · Tutorial
Like (8)
Save
Tweet
Share
34.41K Views

Join the DZone community and get the full member experience.

Join For Free

Before Java EE 6, components could be injected in the following ways:

  • Through the @EJB annotation, where your class needs to be an EJB or Servlet.

  • Through the @Resource annotation, where your class needs to be an EJB or Servlet.

  • Through the @WebServiceRef annotation in web services.

  • Using a framework that implements DI such as: Spring (@Autowired) or JBoss Seam (@In), among others.

When Java EE 6 introduced the Contexts and Dependency Injection (CDI) specification, I was amazed that Java EE finally included dependency injection (DI) horizontally. In other words, any component can be injected into any other component, regardless of whether it's an EJB, a web service, or a POJO. Thus, you can inject a component from a Java EE container using the @Inject annotation, since the file named beans.xml is present in the WEB-INF/META-INF directory to indicate to the container which classes should be scanned.

Some questions appeared in my head after the new spec was released, and I considered the following:

  • Regarding the frameworks that provide DI: do I have to migrate to Java EE and forget they exist? No, you must think in CDI when you want to migrate a full profile of Java EE container.

  • Regarding the @EJB annotation: is it now deprecated? No, you can use the @EJB annotation normally, but this annotation isn't needed when you want to inject local components. In this case, I suggest to use @Inject and forget @EJB because CDI attends to both components.

  • Which annotation should be used with JSF: @Named or @ManagedBean? @Named, because some JSF annotations were created to provide similar features offered by the CDI spec, and now they should be discontinued on my vision.

Based on my above considerations, I created five examples that show how to use CDI with some Java EE specifications.

Example 1 - CDI and JAX-WS:

@WebService(portName = "HelpSoapPort", serviceName = "HelpSoapService", 
            name = "HelpWS", targetNamespace = "http://localhost:8080")
public class HelpSoap {

    @Inject HelpCDIService helpCDIService;
    @Inject HelpEJBService helpEJBService;

    @WebMethod
    public String ping() {
        return helpEJBService.ping();
    }
}


In the example above, both components (CDI and EJB) can be injected using the @Inject annotation and applicable within a web service SOAP.

If you want to change the web service to be an EJB, you just have to include an @Stateless, @Stateful, or @Singleton annotation, and no more.

Example 2 - CDI and JAX-RS:

@Path("/helps")
public class HelpsResource {

    @Inject HelpCDIService helpCDIService;
    @Inject HelpEJBService helpEJBService;

    @GET
    @Path("/ping")
    public String ping() {
        return helpEJBService.ping();
    }
}


For the JAX-RS spec, you can do the same thing described previously.

Example 3 - CDI and EJB:

@Stateless
public class HelpEJBService {

    @Inject AnotherHelpEJBService anotherHelpEJBService;

    public String ping() {
        return anotherHelpEJBService.ping();
    }
}


For the EJB spec, you can also use the @Inject annotation to inject another EJB.

Example 4 - CDI and JSF:

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
...
@Named
@RequestScoped
public class FooNamedController {

    @Inject HelpEJBService helpEJBService;

    public String displayWelcomeMessage() {
        return helpEJBService.displayWelcomeMessage();
    }
}


For JSF I suggest using CDI both for exposing components to XHTML pages and for defining scopes. But if you want to use the @ManagedBean annotation with the view scope provided only by JSF, you continue to be able to use CDI, as shown below:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
...
@ManagedBean
@ViewScoped
public class FooManagedBeanController {

    @Inject HelpEJBService helpEJBService;

    public String displayWelcomeMessage() {
        return helpEJBService.displayWelcomeMessage();
    }
}

Example 5 - CDI and JNDI:

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.enterprise.inject.Produces;
import javax.inject.Qualifier;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.sql.DataSource;
import javax.xml.ws.WebServiceRef;

@Singleton
public class JavaEEContainerResourceAdaptor {

    @Qualifier
    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    public @interface DefaultDataSource {}

    @Produces
    @WebServiceRef(lookup = "java:app/foo-app/HelpSoap")
    static HelpSoap helpSoap;

    @Produces
    @Resource(lookup = "java:jboss/datasources/ExampleDS")
    @DefaultDataSource
    static DataSource defaultDS;

    @Produces
    @PersistenceContext(unitName = "DefaultPU")
    @DefaultDataSource
    EntityManager defaultEntityManager;

    @Produces
    @PersistenceUnit(unitName = "DefaultPU")
    @DefaultDataSource
    EntityManagerFactory defaultEntityManagerFactory;
}


The code above shows how to provide JNDI resources to be injected using CDI. You need to create an adaptor to expose the resources as producer fields. You can also expose resources as producer methods, but the simpler way is using the @Resource annotation.

Below you'll see how to inject these resources using the @Inject annotation and the @DefaultDataSource qualifier from a RESTful web service:

@Path("/helps")
public class HelpsResource {

    private static final int VALIDATION_TIMEOUT_IN_SECONDS = 30;

    @Inject
    @DefaultDataSource
    DataSource dataSource;

    @GET
    @Path("/ping/db")
    public String pingDB() {
        Boolean connected = false;
        try {
            connected = dataSource.getConnection().isValid(
            VALIDATION_TIMEOUT_IN_SECONDS);
        } catch (SQLException e) {
            connected = false;
        }
        return connected ? "Pong!" : "Sorry :(";
    }
}

Conclusion

CDI is quite powerful and will continue being the dependency injection mechanism of Java EE for a long time. I also believe that gradually specifications that provide some kind of DI like EJB will be replaced by features offered by the CDI.

Java EE Dependency injection Java (programming language) Annotation CDI Web Service

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Best Use Java Records as DTOs in Spring Boot 3
  • Java REST API Frameworks
  • NoSQL vs SQL: What, Where, and How
  • Detecting Network Anomalies Using Apache Spark

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: