JAX-RS: Life-cycle, part 1

April 2, 2010 4 min read

This article originally appeared on rand(alex).

I know, we all do it. We start to play with new technology, start with some example, take shortcuts, read blogs, google when a problem pops up... But what we almost never do it read the spec. Well working in a company where we make products that comply to specs, I learned a few things about those specs. For starters, they are almost always boring, but they are full of useful information.

So to prepare for a presentation about JAX-RS, I picked up the spec and read it. And as expected I found lots of interesting stuff out, and now I understood why, while preparing the examples, I had some problem. So I decided to use some of the concept found in the spec and used them in my presentation.

Well now my presentation is over, I will try and share some of it here on my blog. So, to start of JAX-RS is the latest addition to the J2EE6 spec to build RESTful Web Services, but if your reading this you probably already know that, and this article is not an introduction but some look at the internals of the specification.

Let's have a look at the life-cycle of a Resource in JAX-RS. Understanding the life-cycle will help you troubleshoot problems in your application. So what is the life-cycle of a simple resource. An example:

java
@Path("lifecycle/constructor/{segment}")
@Produces("text/plain")
public class LifeCycleResource {
  private String _segment;
  private int _qPage;
  private int _qEntries;

@HeaderParam("Accept") private String _accept;

public LifeCycleResource(
      @PathParam("segment") String seqment,
      @QueryParam("page") int page,
      @QueryParam("entries") @DefaultValue("10") int entries) 
  {
    _segment = seqment;
    _qPage = page;
    _qEntries = entries;
  }

OK, we have our example. Now let's look at what the spec and it's description of the life-cycle.

  1. Path's are matched with Resource classes.
  2. Constructor is called.
  3. Dependencies are injected.
  4. Appropriate method is called.
  5. Resource is garbage collected.

So when accessing the resource though the URI web-app/lifecycle/constructor/something?start=2. We know the following steps are happing:

  • All classes with a @Path annotation are searched for the matching path, so the example Resource will be found because life-cycle/constructor/something has the closes match to the lifecycle/constructor/{segment}
  • Next the constructors of the class are scanned for the closest match, we have one, so that was easy.
  • Now the class is instantiated with that constructor, looking for the annotations on the parameters and filling in the appropriate values. In this case a part of the path to segment, the query parameter to start , and because entries has a default value it will get the value 10.
  • Now the resource is constructed, and the injection can begin. It scans the field for known annotations and initializes those fields (note: remember this point).
  • And finally the methods are scanned for annotations (another path annotation or the http verbs). Here it's found the get method, because it is annotated with @GET and that one is called, it will return a value and that value will be send to the client.
  • The resource is de-referenced and is prepared to be garbage collected.

We've gone over the sequence of one call from the client. What can we tell about of what is safe? Well it's safe to use the fields, without worrying about concurrent calls, except static fields. This shows that each resource doesn't match a servlet, but we have one servlet that manages the life-cycle of these resources.

But there is a gotcha as well, and that is the injection. Because the injection happens after the object is constructed means you can't injection fields in the constructor. In our example we can't use the _accept field because at that time it still is null. So don't wonder why you get NPE's when you use them there. You can use them afterwards when the framework calls the method.

That's enough for now, in the next article I'll look at sub-resources.

© 2009-2026 Alex Van Boxel. All rights reserved.