Acciente Company Logo

Using Controllers in Induction

  1. Using Controllers in Induction
    1. Lifecycle Management
      1. Instantiation
      2. Reloading
      3. Deallocation
    2. Conclusion

This tutorial covers controllers, building on our introduction in the Getting Started Tuturial. Let's start by restating some key aspects of controllers introduced previously:

Type Description
Request facade to the servlet request, extends javax.servlet.http.HttpServletRequest
Response facade to the servlet response, extends javax.servlet.http.HttpServletResponse
Form provides access to the HTML form (if any) submitted with this request
<model_class_name> instance of a developer provided model class, the instance is managed to conform to a user specified lifecycle (also referred to as scope)
ControllerResolver.Resolution provides access to the controller resolution object (useful for writing generic parameterized controllers)

Shown below is a sample controller that illustrates some of the above features.

/**
 * An example of a multi-action controller 
  */
public class UserProfileController implements Controller
{
   /**
    * Action to open a user profile 
    */
   public void open( UserProfileApp userProfileApp, Form form ) throws IOException
   {
      // some sample code follows ...
      userProfileApp.open( form.getString( "userId" ) );
      ...
   }

   /**
    * Action to save a user profile 
    */
   public void save( UserProfileApp userProfileApp, Form form ) throws IOException
   {
      // some sample code follows ...
      userProfileApp.setFirstName( form.getString( "firstName" ) );
      userProfileApp.setLastName( form.getString( "lastName" ) );
      ...
      userProfileApp.save( );
      ...
   }

   /**
    * Action to close a user profile
    */
   public void close( UserProfileApp userProfileApp ) throws IOException
   {
      // some sample code follows ...
      userProfileApp.close( );
      ...
   }
} 

In the example above, first note that the handler methods (open, save and close) have names meaningful to our application (and not the framework!). In the above example UserProfileApp is an example of a developer provided model class, the Form is an Induction provided model class. Values for both the userProfileApp and form are injected by Induction.

Lifecycle Management

For a given controller class, Induction maintains no more than one instance of the controller class (we say "no more" since there would be zero instances for a controller to which no calls have been made).

Since a single controller instance is used to handle requests, the handler methods of a controller are expected to be thread-safe (this is similar to the service() method of the javax.servlet.Servlet interface). Next let's take a closer look at how Induction instantiates a controller.

Instantiation

To illustrate our discussion we will describe the lifecycle semantics in the context of a controller class named CartController. When Induction receives a request directed to CartController it first checks in the controller pool if there is already an instance of CartController.

If this is the first request to the CartController then there will be no CartController in the pool. Induction creates an instance of our CartController class as follows:

After instantiation, the controller is used to handle the web request. Next we look at how Induction reloads controllers.

Reloading

On every call to the CartController class, if the CartController class was initially loaded using Induction's reloading classloader, a check is made to see if the CartController's underlying class file has changed. If the reloading classloader was not used to load the CartController class this check gets bypassed.

If the reloading classloader reloads CartController class as a result of the underlying class file changing:

Next lets take a look at the deallocation semantics.

Deallocation

When it comes time to deallocate an instance of our CartController controller, Induction checks if the CartController class has a public no-arg method named destroy. A destroy method is completely optional. If a destroy() method is defined, Induction calls the method on the controller instance after removing the controller from the pool.

Conclusion

This tutorial described how Induction instantiates and deallocates controllers. It also introduced how you may optionally provide init and/or destroy methods to contain any initialization and tear down code 2.

__
1. Ofcourse the new controller instance is created using the same steps we discussed for creating the first controller instance.

2. It turns out that the object lifecycle semantics discussed in this tutorial are not unique to controllers. In fact it is very close to a discussion of the semantics used by Induction to instantiate several user-provided classes used as configuration plug-ins. These will be covered in a future tutorial. In general, the parameter values injected by Induction into the public constructor (and the optional init method) depend on the context in which the object is instantiated.

For example, in the case of controllers only a value for the javax.servlet.ServletConfig class is injected. But for a templating engine plug-in many more values are injected (for now these are documented in the javadoc documentation).