zoukankan      html  css  js  c++  java
  • Springmvc +JNDI 在Tomcat下 配置数据源(转)

    一、             简介

    jndi(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。

    二、             tomcat配置jndi有三种方式。

    第一种:单个应用独享数据源

    在Tomcat的server.xml找到工程的Context节点,添加一个私有数据源

    1. <Context docBase="Web" path="/Web" reloadable="true" source="org.eclipse.jst.jee.server:WebApp"> 
    2. <Resource name="jndi/testdb"    //指定的jndi名称,会用于spring数据源bean的配置和
    3.             auth="Container"   
    4. 16.  </Context>
    1.             type="javax.sql.DataSource"   //数据源床型,使用标准的javax.sql.DataSource
    2.             driverClassName="com.mysql.jdbc.Driver"   //JDBC驱动器
    3.             url="jdbc:mysql://localhost:3306/appdb"   //数据库URL地址
    4.             username="root"   //数据库用户名
    5.             password="123456"   //数据库密码
    6.             maxActive="20"   
    7.             maxIdle="10"   //最大的空闲连接数
    8.                 maxWait="10000"      //当池的数据库连接已经被占用的时候,最大等待时间
    9.             removeAbandoned="true"
    10.             removeAbandonedTimeout="180"
    11.             logAbandoned="true"      //被丢弃的数据库连接是否做记录,以便跟踪
    12.             factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" /> 

    优点:简单

    缺点:重用性差

    第二种:配置全局JNDI数据源,应用到单个应用

    1. 在Tomcat的server.xml中GlobalNamingResources节点,在节点下加一个全局数据源

    1. <Resource name="jndi/testdb"    //指定的jndi名称,会用于spring数据源bean的配置和
    2.             auth="Container"   
    3.             type="javax.sql.DataSource"   //数据源床型,使用标准的javax.sql.DataSource
    4.             driverClassName="com.mysql.jdbc.Driver"   //JDBC驱动器
    5.             url="jdbc:mysql://localhost:3306/appdb"   //数据库URL地址
    6.             username="root"   //数据库用户名
    7.             password="123456"   //数据库密码
    8.             maxActive="20"   
    9.             maxIdle="10"   //最大的空闲连接数
    10.                 maxWait="10000"      //当池的数据库连接已经被占用的时候,最大等待时间
    11.             removeAbandoned="true"
    12.             removeAbandonedTimeout="180"
    13.             logAbandoned="true"      //被丢弃的数据库连接是否做记录,以便跟踪
    14.             factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" 
    15. />  

    2. 在Tomcat的server.xml找到要应用此JNDI数据源的工程Context节点,增加对全局数据源的引用ResourceLink

    1. <Context docBase="WebApp" path="/WebApp" reloadable="true">  
    2.     <ResourceLink global="jdbc/mysql" name="jdbc/mysql" type="javax.sql.DataSource" />  
    3. </Context> 

    优点:重用性,可控性

    缺点:配置相对第三种方法要繁琐一点,每个工程都得配

    第三种:配置全局JNDI数据源,应用到所有Tomcat下部署的应用

    1          配置tomcat单个全局数据源。(已验证)

    由于存在同时加载多个web工程,配置之后任何一个web项目都可以使用

    1) 在tomcat的 lib 文件夹下添加 JDBC驱动包。

    2)在tomcat的conf文件夹下的server.xml配置文件中加入:

    1. <Resource name="jndi/testdb"    //指定的jndi名称,会用于spring数据源bean的配置和
    2.             auth="Container"   
    3.             type="javax.sql.DataSource"   //数据源床型,使用标准的javax.sql.DataSource
    4.             driverClassName="com.mysql.jdbc.Driver"   //JDBC驱动器
    5.             url="jdbc:mysql://localhost:3306/appdb"   //数据库URL地址
    6.             username="root"   //数据库用户名
    7.             password="123456"   //数据库密码
    8.             maxActive="20"   
    9.             maxIdle="10"   //最大的空闲连接数
    10.                 maxWait="10000"      //当池的数据库连接已经被占用的时候,最大等待时间
    11.             removeAbandoned="true"
    12.             removeAbandonedTimeout="180"
    13.             logAbandoned="true"      //被丢弃的数据库连接是否做记录,以便跟踪
    14.             factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" 
    15. />  

    这里的factory指的是该Resource 配置使用的是哪个数据源配置类,这里使用的是tomcat自带的标准数据源Resource配置类,这个类也可以自己写,实现javax.naming.spi.ObjectFactory 接口即可。某些地方使用的commons-dbcp.jar中的org.apache.commons.dbcp.BasicDataSourceFactory,如果使用这个就需把commons-dbcp.jar及其依赖的jar包,都放在tomcat的lib下,光放在工程的WEB-INF/lib下是不够的。

     

    3) 在tomcat的conf文件夹下的context.xml配置文件中加入:

    1. <ResourceLink global="jndi/testdb" name="jndi/testdb" type="javax.sql.DataSource"/>

    把全局的resource直接公开给该tomcat下的所有web工程。

     

    4) 在web项目的web.xml中加入资源引用:(可省略)

    1. <resource-ref>  
    2. <description>JNDI DataSource</description>  
    3. <res-ref-name>jndi/testdb</res-ref-name>  
    4. <res-type>javax.sql.DataSource</res-type>  
    5. <res-auth>Container</res-auth>  
    6. </resource-ref>  

    启动的时候加载tomcat 配置的JNDI 公开数据源,其中res-ref-name值要和server.xml 、context.xml的name值一致。

     

     5)在web项目中配置spring数据源bean信息:

    1. <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    2.      <property name="jndiName">
    3.          <value>java:comp/env/jndi/testdb</value>
    4.      </property>
    5. 5.     </bean>

    直接替换项目WEB-INF/conf/data-access-config.xml 文件中 bean id=”dataSource” 的节点即可使用

    2           配置tomcat多个全局数据源(已验证)

    注意:配置文件步骤与单个项目相同,仅修改文件内容

    1)同上
    2)server.xml新增数据源即可,格式和单个相同,仅修改name

    3) context.xml 新增配置,格式和单个相同

    4)同上(可省略)

    5) dbe2 为数据源一,dbcpccj为数据源二,dataSource中与原框架中区别为下划线部分的内容

    1. <bean id="dbe2" class="org.springframework.jndi.JndiObjectFactoryBean">
    2.     <property name="jndiName">

    3.        <value>java:comp/env/jndi/dbe2</value>
    4.     </property>
    5. </bean>
    6. <bean id="dbcpccj" class="org.springframework.jndi.JndiObjectFactoryBean">
    7.     <property name="jndiName">
    8.        <value>java:comp/env/jndi/dbcpccj</value>
    9.     </property>
    10. </bean>
    11. <bean id="dataSource" class="com.wishbuild.persistent.source.DynamicDataSource">
    12.         <property name="targetDataSources">   
    13.             <map key-type="java.lang.String"  value-type="com.wishbuild.persistent.source.DataSourceType">   
    14.                 <entry value-ref="dbe2" key="dbe2"></entry>  
    15.                 <entry value-ref="dbcpccj" key="dbcpccj"></entry>   
    16.             </map>  
    17.         </property>  
    18.         <property name="defaultTargetDataSource" ref="dbe2"></property>   
    19.     </bean>  

    6)修改 com.wishbuild.persistent.source 包中DataSourceType.java DataSourceLoadServer.java DynamicDataSource.java 三个文件。

    第一个 DataSourceType.java

    将 文件内容:

    public enum DataSourceType {    dbe2, dbcpccj }

    修改为 :

    public class DataSourceType {

        public static final String dbe2 = "dbe2";

        public static final String dbcpccj = "dbcpccj";

    }

    第二个文件 DataSourceLoadServer.java

    将文件内容中使用到 DataSourceType 类的都修改为 String,比如:

    public static void setDataSourceType(DataSourceType dbType)

    修改为:

    public static void setDataSourceType(String dbType)

    第三个文件 DynamicDataSource.java

    将文件内容中使用到 DataSourceType 类的都修改为 String,比如:

           DataSourceType key = DataSourceLoadServer.getDataSourceType();

        修改为:

        String key = DataSourceLoadServer.getDataSourceType();

     

    以上六部配置完成,则JNDI+Tomcat 配置的多个数据源则可以进行动态切换,其中切换数据源代码为 :DataSourceLoadServer.setDataSourceType(DataSourceType.dbe2); 也就是与原先代码相同,多个数据源的好处就在于,只要在该tomcat下面启动的项目,比如 app,web 等项目,都可以调用该tomcat提供的任何数据源。

    优点:重用性,一次性到位

    缺点:没有可控性

    三、             数据源配置在Tomcat/conf/ context.xml 文件或者 server.xml 文件 中的区别:

    server.xml是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而context.xml文件,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),就会自动重新加载这个文件,而不需要重启服务器。

    四、             常见的报错及解决方案

    a)       java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory

    报错详情:

    ……警告: Failed to register in JMX: javax.naming.NamingException: Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory]
    2010-1-18 13:22:37 org.apache.catalina.mbeans.GlobalResourcesLifecycleListener createMBeans
    严重: Exception processing Global JNDI Resources
    javax.naming.NamingException: Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory]……

    问题描述:这是找不到org.apache.commons.dbcp.BasicDataSourceFactory类,这个类在commons-dbcp.jar中,这jar包时放在工程的WEB-INF/lib下的,而不是tomcat的lib下,但tomcat启动时读取它自身的配置(如server.xml),用的不是工程的lib而是tomcat自带的lib,所以必然报错。就算把这个包拷到tomcat的lib下也不行,因为commons-dbcp.jar与其他jar包还存在一定的依赖关系。
    解决方案:把tomcat jndi配置中的factory="org.apache.commons.dbcp.BasicDataSourceFactory"改为tomcat自带的factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"。

    b)       Caused by: javax.naming.NameNotFoundException: Name memberMDB is not bound in this Context
    问题描述:大多数是因为配置了全局的resource,但没有link造成的。全局resource就是配置在server.xml中GlobalNamingResources节点里的Resource,这种Resource还需要再在Context节点中配置一个ResourceLink,把全局的resource绑定到工程的局部配置中。
    解决方案:配置全局的 ResourceLink。

    c)        Cannot load JDBC driver class 'com.mysql.jdbc.Driver' java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

    问题描述:因为jndi的配置需要用到mysql的驱动器,所以tomcat的lib下需要加入mysql驱动器的jar包,我用的是mysql-connector-java-5.1.5-bin.jar。
    解决方案:把工程WEB-INF/lib下的mysql-connector-java-5.1.5-bin.jar copy到tomcat的lib下。

    d)      Name [jndi/testdb] is not bound in this Context. Unable to find [jdbc].

    检查配置 tomcat (server.xml和context.xml) 和 web项目中web.xml 和data-access-config.xml的配置文件中命名 是否相同。

  • 相关阅读:
    安全编码1
    VPP tips
    VPP概述汇总
    C语言安全编码摘录
    TCP-proxy
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.4. Matplotlib: plotting
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.3. NumPy: creating and manipulating numerical data
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.2. The Python language
    Scipy Lecture Notes学习笔记(一)Getting started with Python for science 1.1. Python scientific computing ecosystem
    25马5跑道,求最快的五匹马的需要比赛的次数
  • 原文地址:https://www.cnblogs.com/softidea/p/4486124.html
Copyright © 2011-2022 走看看