Dmitri Namiot wrote:

> Ok, but the question was why do you need _servlet_ context ?
> We can follow the same way as JDBC : class.forName(...) etc.
>

Sure, you can create a connection pool object dynamically using Class.forName() or 
whatever.
The singleton pattern (using a static method) can work, as long as you only ever need 
one
connection pool.  But, what happens when you need TWO of them?  (And it might not be 
you that
needs the second -- it might be another application running in the same servlet engine 
as
you)

OPTION 1 -- If you use the "static method" approach like this:

    public class ConnectionPool {

        public static Connection getConnection() { ... }

        ....

    }

then you've got a singleton pattern implementation, and you can't have two different 
ones
(unless you try to embed that logic in your singleton connection pool, which doesn't 
seem
advisable from an O-O design viewpoint).  Any servlet that wants to grab a connection 
just
has to execute:

    Connection conn = ConnectionPool.getConnection();

so no reference to the connection pool itself needs to be stored anywhere.

OPTION 2 -- If you do not use a "static method" approach, your connection pool class 
looks
more like this:

    public class ConnectionPool {

        public Connection getConnection() { ... }

        ...

    }

The difference is that the getConnection() method is not static any more.  This allows 
you to
dynamically instantiate (using Class.forName or whatever) as many connection pools as 
you
need.  But, now you need to call the getConnection() method of a particular *instance* 
of
ConnectionPool.

How does my servlet know how to find a reference to the connection pool it needs?  
There is
no longer a single static method I can call to get a connection.  The issue becomes, 
where do
I store the connection pool object, after I have initialized it, so that it is 
available
later on.  There are a few choices here as well (there are other possible variations 
on the
theme):


ALTERNATIVE 2A -- Store it as the instance variable of my servlet:

    The idea here would be that you create the pool in the
    init method of your servlet, and store it in an instance
    variable of the servlet.  This works fine for access from
    this servlet, but how do you get ahold of it from other
    servlets now that getServlet() is deprecated?  (This was
    the original question on this message thread)

        public class MyServlet extends HttpServlet {

            ConnectionPool pool = null;

            public void init(ServletConfig config) {
                super(config);
                .... set up the connection pool ....
            }

            public void doGet(HttpServletRequest req, HttpServletResponse res)
              throws IOException, ServletException {
                ...
                Connection conn = pool.getConnection();
                ...
            }

        }

    Question from the peanut gallery:  If I do everything in
    one servlet, why do I still need a connection pool instead
    of just a single connection?  Answer:  because servlets are
    multi-threaded, so multiple users might be in the middle of
    your servlet at the same time.  Sharing a connection can
    cause you grief, especially if the underlying database supports
    transactions -- a COMMIT or ROLLBACK affects all statements
    currently being executed on a particular connection.


ALTERNATIVE 2B -- Create my own registry class

    It would not be difficult to create your own class that
    used a static Hashtable to store a bunch of connection
    pools, keyed by some unique name.  Then, the registry
    class would have a static method to get the right connection
    pool, from which you could get a connection.

    public class Registry {

        private static Hashtable pools = new Hashtable();

        public void addPool(String name, ConnectionPool pool) {
            pools.put(name, pool);
        }

        public ConnectionPool getPool(String name) {
            return ((String) pools.get(name));
        }

    }

    Now, your servlet gets a connection by the following process:

        ConnectionPool pool = Registry.getPool("mypool");
        Connection conn = pool.getConnection();


ALTERNATIVE 2C -- Use the ServletContext attributes

    The servlet API provides a very convenient mechanism for
    sharing user data objects between the various servlets that
    make up an application.  It does for you what the registry
    class of Alternative 2B does, without you having to write
    the extra code.  Conceptually, it's exactly like using a session
    to store user-specific objects, except that servlet context
    attributes are shared.

    In this scenario, your servlet gets a connection like this:

        ConnectionPool pool =
            (ConnectionPool) getServletContext().getAttribute("mypool");
        Connection conn = pool.getConnection();

So, you don't *have* to use the servlet context attributes to store your connection 
pools,
but it is a very convenient place to do so.  Reminder -- you can get away with the 
singleton
pattern just fine if you will only ever need one connection pool for the lifetime of 
your
application (although it's necessarily good O-O design, and can open you to debugging
problems as well as security risks).  If you need more than one, you need a place to 
put
them.

Craig McClanahan

___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".

Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html

Reply via email to