Java™ Contexts and
Dependency Injection (JCDI) supports dependency injection in managed
beans. By configuring your web application to be JCDI-enabled, you
can add @javax.inject.Inject annotated fields and
properties. If the annotated fields and properties are valid injection
points with valid JCDI managed beans, then their dependencies will
be resolved during run time. Dependency injection separates the creation
of new instances of Java types
from the use of those Java types
in the code. Dependency injection can allow for more easily testable
code while also improving the ability to manage applications.
About this task
In this task, you configure your application to use JCDI
by adding a beans.xml deployment descriptor.
Then, you create a standard Java API
for RESTful Web Services (JAX-RS) resource type with a @javax.inject.Inject field,
which will be resolved during run time.
The following instructions
describe how you can create a simple JCDI-enabled web application
with JAX-RS:
Procedure
- Add a beans.xml deployment descriptor
to your web application (WAR) in the WEB-INF directory. This indicates that the web application should be a JCDI-enabled
application. The existence of the WEB-INF/beans.xml file
indicates that the archive is a JCDI-enabled archive. You are not
required to add any additional information to the deployment descriptor
for this task. The following example illustrates a basic WEB-INF/beans.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<!-- This is empty on purpose. -->
</beans>
- Create a JAX-RS root resource class. The following
example illustrates a simple JAX-RS root resource class:
package com.example.jaxrs;
@javax.ws.rs.Path("exampleWithInjection")
public class StringResource {
public StringResource() {
/* use a no-argument constructor */
}
@javax.ws.rs.core.Context
private javax.ws.rs.core.HttpHeaders httpHeaders;
@javax.annotation.PostConstruct
private void myPostConstruct() {
/* read from the httpHeaders if required */
}
@javax.ws.rs.GET
@javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN)
public String get() {
return "Hello world!";
}
}
In the previous code, a no-argument constructor was
used. A no-argument constructor is a valid JCDI constructor, which
makes the class a valid JCDI bean. If you want to inject JAX-RS context
objects or parameters during object instantiation, you can use bean
properties or fields. Then use an @javax.annotation.PostConstruct annotated
method, which is called after the object is constructed.
- Add a JCDI lifecycle scope to your JAX-RS classes. The following example illustrates a JAX-RS root resource class
with an @javax.enterprise.context.RequestScopedscope
annotation:
Best practice: Add the
@javax.enterprise.context.RequestScoped annotation
to your root resource classes to ensure that your JAX-RS root resource
class has a unique instance per request. This is the default behavior
in non-JCDI-enabled applications.
bprac
package com.example.jaxrs;
@javax.ws.rs.Path("exampleWithInjection")
@javax.enterprise.context.RequestScoped
public class StringResource {
@javax.ws.rs.GET
@javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN)
public String get() {
return "Hello world!";
}
}
- Create a class that is injected into the JAX-RS root resource. The following example illustrates a standard Java class:
package com.example.jaxrs;
public class Data {
public String getData() {
return "Hello world!";
}
}
- Modify your JAX-RS root resource to add an @javax.inject.Inject annotated
field for the com.example.jaxrs.Data type. The
following example illustrates a modified JAX-RS root resource class
with an @javax.inject.Inject injection point:
package com.example.jaxrs;
@javax.ws.rs.Path("exampleWithInjection")
@javax.enterprise.context.RequestScoped
public class StringResource {
@javax.ws.rs.GET
@javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN)
public String get() {
return myData.getData();
}
@javax.inject.Inject
private Data myData;
}
During run time, when the JAX-RS root resource is
constructed, an instance of the Data type is injected
into the myData field. While this is a simple form
of injection, JCDI allows for more complex use cases. Read the JCDI
specification for additional details.
- Add a Servlet 3.0 web.xml file to
your WAR file. In the following example, a default JAX-RS
application servlet definition is added, which makes all JAX-RS root
resources available in the /rest/* URL pattern:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/
j2ee/web-app_3_0.xsd" version="3.0">
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Results
You have configured a web application to use JCDI, created
a JCDI lifecycle scoped JAX-RS resource, and created a standard injection
point.