`
ericliu1986
  • 浏览: 111162 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

由Tomcat下的JNDI数据源引出的......

    博客分类:
  • J2EE
阅读更多

    众所周知,Tomcat是支持数据库连接池的,并且还支持通过JNDI接口来获得这一服务。要想在你的程序中使用这一特性,需要你对Tomcat做一些配制。


    我以往的做法都是现到网上去找,然后人家说在哪个配制文件下加一段什么代码,就照着做,成功后这事儿也就结了。过了一段时间又遇到这个问题,还是同样的做法......。为了结束这种痛苦的、无休止的循环,我决定花点儿时间把这个问题搞清楚,要做到不仅要知其然还要知其所以然。


Tomcat的配制文件体系(以Tomcat 6.0.18为例)


    在%TOMCAT_HOME%/conf目录下一般会有server.xml、context.xml、web.xml、tomcat-users.xml等配制文件,下面重点说一下server.xml和context.xml两个文件:


1、server.xml
    这个文件是整个Tomcat的一个缩影,从它可以看出Tomcat的架构和工作方式。

Server(1)----元素代表了整个Catalina servlet容器

|
|------ Service(n)----元素代表了一个用于处理请求的组合,这个组合包括了一个或多个Connector和
|         |                    一个Engin,这些Connector共享这个Engin。 

|         |
|         |------ Connector(n)----主要用于监听来自client的请求,一个Connector监听一个端口。
|         |
|         |------ Engin(1)----元素代表了和一个特定联系的,用于请求处理的机构。它接受和
|                   |                     处理来自同属一个Service下的所有Connector的请求,并生成完整的回应(response)
|                   |
|                   |------ Host(n)----元素代表了一个虚拟主机
|                             |
|                             |------ Context(n)----元素代表了一个特定的虚拟主机下的web application
|
|------ GlobalNamingResources(1)----元素定义的是整个容器级别的全局的资源,

                                                                    这些 资源对容器中的每个Web Application都是不可见的。

                                                                    某个Web Application想要使用某个全局资源,可以在此

                                                                    Web Application的   元素下使用元素

                                                                     来引用想要使用的全局资源。


    在这想要说的主要是GlobalNamingResources这个节点。正如上面的说明所述,定义在它下面的资源都是整个容器级别的全局资源,也就是说这些资源可以被部署在这个容器中的所有webapp所使用。但是必须在webapp和这些资源之间搭一座桥------在webapp对应的Context节点下使用元素来引用想要使用的全局资源。


2、context.xml

    从上面我们可以知道一个Host(虚拟主机)下可以有多个Context,每个Context就代表了一个部署在该虚拟主机下的webapp。tomcat 5以后就不推荐大家在server.xml的Host节点下直接追加Context,因为对Host节点下的Context的修改,会导致server.xml改变这样一来就必须要重新起动服务器才能加载新的server.xml。所以在tomcat 5以后就多了context.xml这个文件,在这个文件下配制的资源所有webapp都能够访问到。


    以上是对tomcat做的一些粗略的介绍,回到正题,下面就tomcat下的JNDI数据源的配制来实践一下上面的说法。

方案一:使用%TOMCAT_HOME%/conf/context.xml
    直接上代码:

</Context>    
    <Resource name="jdbc/test"  
              type="javax.sql.DataSource"
              username="root"
              password="mysql"  
              driverClassName="com.mysql.jdbc.Driver"  
              maxIdle="2"  
              maxWait="5000"  
              url="jdbc:mysql://localhost:3306/test"  
              maxActive="4"/>
</Context>

 

        以上的<Resource>节点是针对MySql的数据源配制信息,以上工作做完后,Tomcat起动时就会把这个数据源生成好放到上下文环境中。该Tomcat下的所有webapp都能通过JNDI接口找到该数据源。

 

    这下东西有了,但怎么来找到并使用它呢?

 

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<resource-ref>
	   <description>TomcatJNDI数据源</description>
	   <res-ref-name>jdbc/test</res-ref-name>
	   <res-type>javax.sql.DataSource</res-type>
	   <res-auth>Container</res-auth>
	</resource-ref>
</web-app>

    以上是在自己的webapp下添加对配制在context.xml下的数据源的引用。试验了一下,在Tomcat 6.0.18下这个<resource-ref>不用,也能正确找到那个数据源。但最好还是写上吧!

 

    桥已经搭好了,来试着lookup一下吧!

 

    public static Connection getConnection() {
        Connection conn = null;
        try {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/test");
            conn = ds.getConnection();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(conn != null){
            System.out.println("Connected!");
        }else {
            System.out.println("Connect failed!");
        }
        return conn;
    }

    你"connected"了吗?

 

方案二:使用%TOMCAT_HOME%/conf/server.xml下的<GlobalNamingResources>节点。

    直接上代码:

<Server port="8005" shutdown="SHUTDOWN">
	<GlobalNamingResources>
		<Resource  name="jdbc/test"  
             		   type="javax.sql.DataSource"  factory="" 
                           password="mysql"  
                           driverClassName="com.mysql.jdbc.Driver"  
                           maxIdle="2"  
                           maxWait="5000"  
                           username="root"  
                           url="jdbc:mysql://localhost:3306/test"  
                           maxActive="4"/>
		...
	</GlobalNamingResources>
	...
</Server>

    顾名思义,这也是面向所有webapp的。但跟方案一有所不同的是<GlobalNamingResources>需要跟<ResourceLink>配合使用。详细情况参见下面:

 

<Context>
	<ResourceLink name="jdbc/link" global="jdbc/test" type="javax.sql.DataSource"/>
	...
</Context>

    此时lookup时需要用"java:comp/env/jdbc/link"

    Context ctx = new InitialContext();
            DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/link");

 

方案三:<Host>节点下追加<context>节点。具体内容跟方案一类似,但tomcat5后就不推荐使用这种方法了。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics