zoukankan      html  css  js  c++  java
  • JNDI在Spring和tomcat下的使用

    1. 是什么

    JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一。JNDI 在 J2EE 中的角色就是“交换机” —— J2EE 组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下,提供 JNDI 供应者的容器可以充当有限的数据存储,这样管理员就可以设置应用程序的执行属性,并让其他应用程序引用这些属性(Java 管理扩展(Java Management Extensions,JMX)也可以用作这个目的)。JNDI 在 J2EE 应用程序中的主要角色就是提供间接层,这样组件就可以发现所需要的资源,而不用了解这些间接性。

    2. 为何用

    程序员可以不用关心“具体的数据库后台是什么?JDBC驱动程序是什么?访问数据库的用户名和口令是什么?”等等这些问题,而是把这些问题交给J2EE容器来配置和管理,程序员只需要对这些配置和管理进行引用即可。

    3. 怎么用

    3.1 整体思路

    1. 在在J2EE容器如Tomcat中配置一个数据源,给这个数据源设置一个名称;
    2. 在项目程序中,通过数据源名称引用这个数据源从而访问后台数据库

    3.2 示例

    下面在Tomcat6.0+spring+springMVC+mybatis项目中演示用法。

    Tomcat
    • 方法一:非全局的Resource,只更改context.xml

    在context.xml的根节点Context里加入Resource配置

      <Resource name="jdbc/mmcDB"       //指定的jndi名称,会用于spring数据源bean的配置和ResourceLink的配置
                     auth="Container"//认证方式,一般默认这个
                     type="javax.sql.DataSource"   //数据源床型,使用标准的javax.sql.DataSource
                     driverClassName="com.mysql.jdbc.Driver"    //JDBC驱动器 
                     url="jdbc:mysql://localhost:3306/test" //数据库URL地址             
                     username="test"     //数据库用户名
                     password="test"   //数据库密码
                     maxIdle="40"   //最大的空闲连接数
                     maxWait="4000" //当池的数据库连接已经被占用的时候,最大等待时间
                     maxActive="250" //连接池当中最大的数据库连接
                     removeAbandoned="true" 
                     removeAbandonedTimeout="180"
                     logAbandoned="true" //被丢弃的数据库连接是否做记录,以便跟踪
                     factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" />
    
    • factory:该Resource 配置使用的是哪个数据源配置类,这里使用的是tomcat自带的标准数据源Resource配置类,这个类也可以自己写,实现javax.naming.spi.ObjectFactory 接口即可。

      如果使用其他的数据池,如阿里巴巴的druid,要满足两个条件:

      1. 其实现了javax.naming.spi.ObjectFactory,druid的com.alibaba.druid.pool.DruidDataSourceFactory就实现了
      2. 需把jar及其依赖的jar包 ,都放在tomcat的lib下,光放在工程的WEB-INF/lib下是不够的。阿里巴巴的druid依赖log4j,所以后者的jar也要复制进去
    • driverClassName的其他写法:

      oracle:oracle.jdbc.driver.OracleDriver

      db2:com.ibm.db2.jcc.DB2Driver

      SQLServer:com.microsoft.sqlserver.jdbc.SQLServerDriver

    • url的其他写法示例:

      oracle:jdbc:oracle:thin:@192.168.1.249:1521:XE

      db2:jdbc:db2://18.1.99.7:55555/esdb:currentSchema=EMPSAL

    • 这种配法可写多个resource给不同的项目使用

    • 方法二:全局的 Resource,更改server.xml和context.xml

      • server.xml:在server.xml的GlobalNamingResources节点里加入Resource,再在Context节点里加入ResourceLink的配置。全局的resource只是为了重用,方便所有该tomcat下的web工程的数据源管理,但如果你的tomcat不会同时加载多个web工程,也就是说一个tomcat只加载一个web工程时,是没有必要配置全局的resource的。
      把上面的context.xml的Resource标签加内容直接拷贝到server.xml的GlobalNamingResources标签里就行了
      
      • 接下来有四种方式引用这个全局的Resource

        方法2没弄出来,方法1,3,4是可以的,事实上3和4是同一种方法,只要在建项目时在项目的webapps/mmc/META-INF/下写好context.xml,这两个方法所要求的context.xml都会在启动tomcat后自动生成(tomcat7.0没有自动生成,不过这样写过后相当于用来方法4,一样可以成功启动)

        1. 直接在conf/context.xml里引用
        <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>      
        
        1. 这个方法我用tomcat6.0和7.0都失败了,报找不到mmcDB,暂时用不到就不深究了,列出了给大家参考吧 ......conf/server.xml里继续配置,该方法可以指定把哪些source绑定到哪个web工程下。
        <!-- 在host标签内新增,第一行为加载的工程配置,第二行是该工程需要的ResourceLink配置 -->
        <context docBase="mmc" path="" reloadable="false"> 
             <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>
        </context>
        
        1. 安装目录下的conf/Catalina/localhost/下建立一个xml文件,文件名是<yourAppName>.xml。比如工程名为mmc,则该xml名为mmc.xml。
        <?xml version="1.0" encoding="UTF-8"?>
        <Context>   
             <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>       
        </context>
        
        1. tomcat安装目录下的webapps estMETA-INFcontext.xml的Context节点中增加:
        <ResourceLink global="jdbc/mmcDB" name="jdbc/mmcDB" type="javax.sql.DataSource"/>
        
    Spring
    • 方法一:
    <bean id="testDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
         <property name="jndiName">
              <value>java:comp/env/jdbc/mmcDB</value>
         </property>
    </bean>
    或者:
    <bean id="testDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
         <property name="jndiName">
              <value>jdbc/mmcDB</value>
         </property>
         <property name="resourceRef">
              <value>true</value>
         </property>
    </bean>
    
    • 方式二:
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/mmcDB" />
    

    3.3 细节解释

    • Tomcat中在server.xml下配置你必需重启服务器才能生效,而context.xml配置保存后tomcat会自动加载无需重启

    • JNDI地址写法:AB两种地址的用法可点击参考资料的第一条链接查看
      在描述JNDI,例如获得数据源时,JNDI地址 有两种写法,例如同是 jdbc/testDS 数据源:
      A: java:comp/env/jdbc/testDS
      B: jdbc/testDS
      这两种写法,配置的方式也不尽相同,用A就行了别纠结,网上查了一堆资料都说的乱七八糟。
      java:comp/env 是环境命名上下文(environment naming context(ENC)),是在EJB规范1.1以后引入的,引入这个是为了解决原来JNDI查找所引起的冲突问题,也是为了提高EJB或者J2EE应用的移植性。
      在J2EE中的引用常用的有:
      JDBC 数据源引用在java:comp/env/jdbc 子上下文中声明
      JMS 连接工厂在java:comp/env/jms 子上下文中声明
      JavaMail 连接工厂在java:comp/env/mail 子上下文中声明
      URL 连接工厂在 java:comp/env/url子上下文中声明

    4. 参考资料

    1. http://stackoverflow.com/questions/4099095/what-does-javacomp-env-do
    2. http://blog.csdn.net/cyong888/article/details/7361466
  • 相关阅读:
    leetcode 131. Palindrome Partitioning
    leetcode 526. Beautiful Arrangement
    poj 1852 Ants
    leetcode 1219. Path with Maximum Gold
    leetcode 66. Plus One
    leetcode 43. Multiply Strings
    pytorch中torch.narrow()函数
    pytorch中的torch.repeat()函数与numpy.tile()
    leetcode 1051. Height Checker
    leetcode 561. Array Partition I
  • 原文地址:https://www.cnblogs.com/wuyanshun/p/6763162.html
Copyright © 2011-2022 走看看