在资源注入的多个servlet中使用DataSource

时间:2014-08-01 16:41:56

标签: java java-ee servlets ejb datasource

我想要在多个servlet中使用javax.sql.DataSource。我不喜欢指定:

的想法
@Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
private DataSource liveDataSource_;

在每个servlet中,因为在我看来框架必须为每个servlet查找DataSource,如果DataSource的名称发生变化,每个servlet也必须改变。

我的想法是声明一个可以在每个servlet中声明的Singleton EJB:

@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class DataSources {  
    @Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
    private DataSource liveDataSource_;

    public synchronized Connection getLiveConnection() throws SQLException {
        return liveDataSource_.getConnection();
    }
}

这是解决问题的合理方法吗?对于我认为会成为常见问题的事情,我觉得它有点沉重。

2 个答案:

答案 0 :(得分:0)

总的来说,IMO没问题。 但请不要让bean返回连接,而是直接返回DataSource。 像WebSphere这样的一些AppServers会在再次放置bean上下文时自动关闭连接。

另一个解决方案是使用@Resource(name =“myds”)而不是查找。 如果所有Servlet都在一个Web应用程序中,那么您可以在web.xml中使用res-ref-name myds定义一个resource-ref,并将其解析为仅在该位置的真实查找名称。

答案 1 :(得分:0)

我认为仅仅因为这个原因使用EJB可能会因为你写的而有点过重。

首先,大多数现代应用程序服务器都会缓存该查找,因此不会那么昂贵。

第二 - 您可以使用@Resource(name =“myds”),因为Robert说它将使用相同的资源引用,可以使用应用程序服务器的映射函数映射到JNDI名称。

第三 - 你可以使用CDI来获得这样的网络模块解决方案:

创建保存DataSource定义的类,如下所示:

public class Datasources {

    @Produces @Resource(name="jdbc/yourRef", lookup="yourJNDI")
    DataSource myDataSource;
}

然后使用Inject:

使用它
public class MyServlet extends HttpServlet {
    @Inject 
    private DataSource myDs;