在Java EE Web应用程序中缓存InitialContext和DataSource

时间:2011-02-19 00:38:50

标签: jdbc java-ee restlet-2.0 connector-j

在以下JDBC / MySQL的Connector / J引用中,它建议我们缓存InitialContext和Datasource的实例。只是让它成为私有静态实例解决缓存?难道不应该关心线程安全(如果有的话)?什么是为web-app(Restlet + glassfish / Java EE + mysql)缓存这个的最佳“地方”?

有一个GenericDAO类,它是数据访问类的 root ,可以这么说。那么只有静态实例才能真正解决问题吗?它会强制一些我们不想要的静态方法。建议??

谢谢!

public void doSomething() throws Exception {
/*
* Create a JNDI Initial context to be able to
* lookup the DataSource
**
In production-level code, this should be cached as
* an instance or static variable, as it can
* be quite expensive to create a JNDI context.
**
Note: This code only works when you are using servlets
* or EJBs in a Java EE application server. If you are
* using connection pooling in standalone Java code, you
* will have to create/configure datasources using whatever
* mechanisms your particular connection pooling library
* provides.
*/
InitialContext ctx = new InitialContext();
/*
* Lookup the DataSource, which will be backed by a pool
* that the application server provides. DataSource instances
* are also a good candidate for caching as an instance
* variable, as JNDI lookups can be expensive as well.
*/
DataSource ds =
(DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

/*
*Remaining code here...
*/
    }

2 个答案:

答案 0 :(得分:4)

如果您使用的是JAX-RS,则可以使用@Context注释。

E.g。

@Context
private ServletContext context;

@GET
@Path("whatevers")
public List<Whatever> getWhatevers() {
    DataSource dataSource = Config.getInstance(context).getDataSource();
    // ...
}

但是,如果您的Restlet环境也支持@Resource注释,您可以将其用作良好的。

@Resource(mappedName="jdbc/MySQLDB")
private DataSource dataSource

这在技术上更好地放置在EJB中,然后由@EJB在您的Web服务中注入。

@Stateless
public class WhateverDAO {

    @Resource(mappedName="jdbc/MySQLDB")
    private DataSource dataSource

    public List<Whatever> list() {
        // ...
    }

}

@EJB
private WhateverDAO whateverDAO;

@GET
@Path("whatevers")
public List<Whatever> getWhatevers() {
    return whateverDAO.list();
}

答案 1 :(得分:2)

跟进BalusC的link,我可以确认在使用Restlet时我们可以做同样的事情。但是,根据the example中的代码获取配置实例,您将传递ServletContext作为参数。 Restlet就像是“另一个”框架,它使用Servlet作为适配器来配置自身。因此,将ServletContext作为参数从代码中的其他位置传递是非常棘手的(Restlet使用它自己的 Context 对象,它在概念上类似于ServletContext)

对于我的情况,返回缓存数据源的静态方法似乎“足够干净”,但可能有其他设计/组织方法。