Application developers can use Java™ Contexts and Dependency Injection (JCDI)
to have different scopes for their managed beans. For instance, if
you 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.
About this task
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 your 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 your 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, you must use
@javax.enterprise.context.ApplicationScoped.
bprac
The
following instructions describe how you can use lifecycle scopes for
a simple JCDI-enabled web application with JAX-RS:
- 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 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("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.
bprac
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,
you must 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> httpHeaders,
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.