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