我有一个在Tomcat 6中配置为MyDataSource的DataSource。我用下面的方式取回它
DataSource dataSource;
try {
dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource");
} catch (NamingException e) {
throw new DaoConfigurationException(
"DataSource '" + url + "' is missing in JNDI.", e);
}
一切正常。现在我要将这些代码导出到Jboss AP 6。并且我将我的数据源及其连接池配置为同名的local-tx dataSource。
当我执行上面的代码时,我得到了NamingException异常。经过一番调查,我发现在Jboss下调用数据源的正确方法是
dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");
谁能解释我为什么要省略"comp/env"在我的JNDI路径下的Jboss?
java:comp/env
)的JNDI名称,然后将该逻辑引用映射到应用程序服务器中定义的物理资源,其JNDI名称是应用程序服务器供应商专有的。这种方法使您的代码和程序集可以移植到任何兼容的应用程序服务器。
步骤1:声明和查找资源引用
选项1
这可以通过在你的web部署描述符(WEB-INF/web.xml
)中声明一个resource-ref
来完成:
<resource-ref>
<description>My Data Source.</description>
<res-ref-name>jdbc/MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
在您的代码中,您可以使用JNDI名称java:comp/env/jdbc/MyDataSource
:
查找此资源。dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");
无论应用程序部署在哪个服务器上,这个JNDI名称都不会改变。
选项2
或者,从Java EE 5 (Servlet 2.5)开始,使用@Resource
注释可以在代码中更容易地完成此操作。这消除了在web部署描述符(web.xml)中配置资源引用的需要,并防止了执行显式JNDI查找的需要:
public class MyServlet extends HttpServlet {
@Resource(name = "jdbc/MyDataSource")
private DataSource dataSource;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// dataSource may be accessed directly here since the container will automatically
// inject an instance of the data source when the servlet is initialized
}
这种方法与前一种方法具有相同的结果,但减少了程序集中的样板代码和配置。
步骤2:将资源引用映射到数据源
然后,您将需要使用应用程序服务器的专有方法将资源引用映射到您在服务器上创建的物理数据源,例如,使用JBoss的自定义部署描述符(WEB-INF/jboss-web.xml
):
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/MyDataSource</jndi-name>
</resource-ref>
</jboss-web>
或者,例如,使用Tomcat的context.xml
:
<Resource name="jdbc/MyDataSource" . . . />
您可以在数据源定义中添加'jndi-name'标签:
JNDI -name -数据源应该被绑定到的JNDI名称。
您可以在JBoss wiki上找到数据源文档:ConfigDataSources