简体   繁体   English

在具有资源注入的多个servlet中使用数据源

[英]Using a DataSource in multiple servlets with resource injection

I have a javax.sql.DataSource that I want to use in multiple servlets. 我有一个要在多个servlet中使用的javax.sql.DataSource I don't like the idea of specifying: 我不喜欢指定的想法:

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

in every servlet as it seems to me that the framework will have to be looking up the DataSource for every servlet and if the name of the DataSource changes, every servlet will have to change too. 在我看来,在每个servlet中,该框架都必须为每个servlet查找数据源,如果DataSource的名称发生更改,则每个servlet也都必须更改。

My idea is to declare a Singleton EJB that can then be declared in each servlet: 我的想法是声明一个Singleton EJB,然后可以在每个servlet中声明它:

@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();
    }
}

Is this a reasonable way of solving the issue? 这是解决问题的合理方法吗? I feel it's a bit heavy handed for something I would have thought would be a common issue. 我觉得对于某些我认为将是普遍问题的事情来说,这有点费力。

In general it's ok IMO. 总的来说,IMO没关系。 But please don't let the bean return the connection but directly the DataSource. 但是请不要让Bean返回连接,而是直接返回DataSource。 Some AppServers like WebSphere will automatically close the connection when the bean context is left again. 再次离开Bean上下文时,某些类似WebSphere的AppServer将自动关闭连接。

Another solution would be to use @Resource(name="myds") instead of lookup. 另一种解决方案是使用@Resource(name =“ myds”)代替查找。 If all your Servlets are in one Web Application then you can define one resource-ref with res-ref-name myds in your web.xml and resolve it to the real lookup name only at that place. 如果所有Servlet都在一个Web应用程序中,则可以在web.xml中定义一个带有res-ref-name myds的resource-ref,然后仅在该位置将其解析为真实的查找名称。

I'd say that using an EJB only for that reason may be a bit too heavy as you wrote. 我会说,仅由于这个原因而使用EJB可能会像您所写的那样过于繁琐。

First most of modern application servers will cache that lookup so it will not be that costly. 首先,大多数现代应用程序服务器将缓存该查找,因此它不会那么昂贵。

Second - you can use @Resource(name="myds") as Robert said which would use same resource reference, that can be mapped to the JNDI name using application server's mapping functions. 其次-您可以使用@Resource(name =“ myds”),正如Robert所说的,它将使用相同的资源引用,可以使用应用程序服务器的映射功能将其映射到JNDI名称。

Third - you could use CDI to have web module only solution like this: 第三-您可以使用CDI拥有仅Web模块的解决方案,如下所示:

Create class which hold your DataSource definition like this: 创建包含您的DataSource定义的类,如下所示:

public class Datasources {

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

And then use it servlet using Inject: 然后通过Inject使用它servlet:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM