Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
359 views
in Technique[技术] by (71.8m points)

java - What is that Application class lifecycle of a rest service?

Is every rest service starting with extending that application class and defining applicationpath? What is the lifecyce of that application class itself? Here is an example:

import javax.ws.rs.core.Application;
@javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends Application {}

Is this a servlet? Is it always alive? How shall I understand this class? Is it a cdi bean? Does the server creates this class on every request?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What is Application?

Application is a deployment agnostic abstract class provided by JAX-RS for configuring and registering the components of a JAX-RS application and it's also used to supply additional metadata to the application.

Application is one of the types that can be injected using the @Context annotation. For more details, refer to this answer.

Subclasses of Application

Application subclasses can implement methods such as getClasses(), getSingletons() and getProperties() for configuring and registering components and properties.

Application subclasses can be annotated with @ApplicationPath, defining the base URI for the JAX-RS resource classes (classes annotated with @Path). Application subclasses are instantied once when the web application starts and they are managed by the JAX-RS runtime.

The simplest implementation possible is as following:

@ApplicationPath("api")
public SampleApplication extends Application {

}

In the example above no resources classes or providers are registered, so the JAX-RS runtime will scan the classpath for JAX-RS components and will register them automatically.

However, according to this post from Jakub Podlesak, this approach is discouraged in production environments:

The above example works great. When started, the application just scans the actual class-path, and adds every single JAX-RS component class found there to the actual runtime configuration. Isn't is great? Frankly, this kind of configuration could work just fine. Until someone changes either the system configuration (system class-path) or the way how you application is being packaged (a new 3rd party component could be added/removed from the application class-path then). These changes could be out of your control and if one of them happens, you application configuration could break. For this reason, it is not wise to use this kind of configuration in a production environment.

Jersey, the JAX-RS reference implementation, provides the ResourceConfig class. Compared to Application, ResourceConfig provides advanced capabilities to simplify registration of JAX-RS components, such as scanning for root resource and provider classes in a provided classpath or a in a set of package names, etc. For more details, refer to the Jersey documentation.

Working with multiple Application subclasses

Is also worth mentioning that you are not restricted to a single Application subclass per web application. The same WAR can have multiple Application subclasses. For more details, have a look at this post from Adam Bien:

To deploy multiple JAX-RS applications with different URIs in one WAR you will have to create one javax.ws.rs.core.Application subclass per such an application (or use web.xml for this purpose). Obviously the in Java EE ubiquitous Convention over Configuration (or Configuration by Exception) cannot work any more: you will have to explicitly configure resources in each subclass by overriding the method getClasses or getSingletons:

@Path("first")
public class FirstResource {

    @GET
    public String first() {
        return "first";
    }
}
@ApplicationPath("one")
public class JAXRSConfigurationOne extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new HashSet<>();
        resources.add(FirstResource.class);
        return resources;
    }
}
@Path("second")
public class SecondResource {

    @GET
    public String first() {
        return "second";
    }
}
@ApplicationPath("two")
public class JAXRSConfigurationTwo extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new HashSet<>();
        resources.add(SecondResource.class);
        return resources;
    }
}

Both JAX-RS applications become accessible through distinct URIs: http://localhost:8080/multiple-roots/one/first and http://localhost:8080/multiple-roots/two/second

What if no Application subclass is present?

If no Application subclass is present, the JAX-RS implementations are required to add a servlet and set its name to javax.ws.rs.Application and to automatically discover all resource classes and providers which must be packaged with the application.

For further details, have a look at the chapter 2 of the JAX-RS 2.1 specification.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...