Network Deployment (Distributed operating systems), v8.0 > End-to-end paths > Web services - RESTful services > Use Java contexts and dependency injection with JAX-RS > 4. Implementing JAX-RS resources with JCDI functionality.
Implement JAX-RS resources with different lifecycle scopes
Application developers can use Java Contexts and Dependency Injection (JCDI) to have different scopes for their managed beans. For instance, if we have an @javax.enterprise.context.ApplicationScoped annotation on a Java class named Foo and multiple @javac.inject.Inject annotated Foo fields in managed beans, there is only one application-scoped Foo instance that actually exists.
Lifecycle scopes can help application developers manage their code. For example, by giving Java types a simple scope annotation, you can ensure that a single, managed instance is created for that scope, instead of having to potentially write multiple lines of code to guarantee the behavior that you want.
Lifecycle scopes only apply to managed beans. If the application code creates a new instance of a class, your code controls the entire lifecycle of that single instance. However, in managed code such as Java API for RESTful Web Services (JAX-RS) resource classes where the runtime environment creates new instances for you, the JAX-RS runtime environment assumes responsibility of the lifecycle of your classes.
Add specific lifecycle scopes to any JAX-RS root resource and provider classes that exist in the application, in a JCDI-enabled archive. For JAX-RS resource classes with an @javax.ws.rs.Path annotation, you can use @javax.enterprise.context.RequestScoped. For javax.ws.rs.core.Application sub-classes and @javax.ws.rs.ext.Provider annotated classes, use @javax.enterprise.context.ApplicationScoped.
The following instructions describe how you can use lifecycle scopes for 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. 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 it 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 //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ :/ /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("exampleWithLifecycle") public class StringResource { @javax.ws.rs.GET @javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN) public String get() { return "Hello world!"; } }
- Add a JCDI lifecyle scope to your JAX-RS classes. Add the @javax.enterprise.context.RequestScoped scope annotation to your root resource classes:
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.
package com.example.jaxrs; @javax.enterprise.context.RequestScoped @javax.ws.rs.Path("exampleWithLifecycle") public class StringResource { @javax.ws.rs.GET @javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN) public String get() { return "Hello world!"; } }- (optional) For any custom @javax.ws.rs.ext.Provider annotated classes or javax.ws.rs.core.Application subclasses, add @javax.enterprise.context.ApplicationScoped to your class. The following example illustrates how to modify your JAX-RS provider or application sub-class with an @javax.enterprise.context.ApplicationScoped scope annotation:
package com.example.jaxrs; @javax.enterprise.context.ApplicationScoped @javax.ws.rs.ext.Provider public class Example implements javax.ws.rs.ext.MessageBodyWriter <CustomType> { public long getSize(String t, Class <?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) { return -1; } public boolean isWriteable(Class <?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) { return CustomType.class == type; } public void writeTo(String t, Class <?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType, javax.ws.rs.core.MultivaluedMap <String, Object> //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ Headers, OutputStream entityStream) throws IOException { /* write something to the entity stream */ } }
Results
You have configured a web application to use JCDI, and created a JCDI, lifecycle-scoped JAX-RS resource and provider.
Implement a JAX-RS resource with decorators and method interceptors
Implement JAX-RS resources with dependency injection
Use Java contexts and dependency injection with JAX-RS
Related
Web services specifications and APIs