views:

222

answers:

4

Servlets 101, under Tomcat 6:

Could someone kindly point me to a good explanation of the best way to eg. create a Collection of expensive Foo objects at servlet startup time and stash them somewhere where I can access them while processing each request?

Near as I can tell there are at least three ways to do this and I am a bit fuzzy on the difference. I am not concerned with clustering or algorithms to evict stale entries or anything like that, just the basics.

Cheers and Thanks.

+1  A: 

You have several options:

  • Use commons-pool, initiate your objects at boot and then borrow them from the pool.
  • Make sure that you really need a pool of objects. In many cases you can create just one object and access it in a thread safe manner. A good place to look is at the spring framwork.
David Rabinowitz
+2  A: 

Implement a ServletContextListener, do the desired loading task during contextInitialized() and store the result in the application scope by ServletContext#setAttribute(). It will be invoked during server's startup and the application scope is accessible inside regular servlets as well.

Basic example:

public class Config implements ServletContextListener {
   public void contextInitialized(ServletContextEvent event) {
        List<Foo> foos = fooDAO().list();
        event.getServletContext().setAttribute("foos", foos);
    }
}

Map it in web.xml the usual way:

<listener>
    <listener-class>mypackage.Config</listener-class>
</listener>

Here's how to access it in regular servlets:

protected void doSomething(request, response) {
    List<Foo> foos = (List<Foo>) getServletContext().getAttribute("foos");
}

And here's how you can access it in JSPs:

<c:forEach items="${foos}" var="foo">
    ${foo.someProperty}<br>
</c:forEach>

That said, I really don't see how that is related to "servlet pool". This term makes no sense.

Hope this helps.

BalusC
thanks,,,What is the main diference between contextInitialized interface method and init() ? could you clarify more ?
worldpython
A: 

You are looking for an object pool. Typically an object pool is built using a list of free objects, adding to the list when resources are freed while the maximum amount of free objects is not reached.

I would not fill the pool upfront, just allocate a new object if the pool of free objects is empty.

One notable performance win is to keep 1 reference for the last freed object. Not having to add it to the list of free objects saves a lot for situations where 1 object is allocated and freed alternatively. If the reference is not null add the next freed object to the list, on allocation return the last freed and null it.

rsp
A: 

You can use the servlet context.

The servlet context is common to all servlets instances and its life cycle goes beyond the request and session.

You can put anything there like:

public void doGet( HttpServletRequest request, HttpServletResponse response ) {

     ServletContext sc = getServletContext();

     List expensiveObjectList = ( List ) sc.getAttribute("someName");
     if( expensiveObjectList == null ) {
         expensiveObjectList = someExpensiveInitializationMethod();
         sc.setAttribute( "someName", expensiveObjectList );
     }

     // use the list... 
}

Here's a link where you can read more about it

OscarRyz