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的配置文件中命名 是否相同。

  • 相关阅读:
    安卓开发学习笔记(七):仿写腾讯QQ登录注册界面
    android studio 撤销和恢复
    安卓开发学习笔记(六):如何实现指定图片定时开屏功能?
    JAVA小白开发环境配置(编译器为Idea)
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    安卓开发学习笔记(五):史上最简单且华丽地实现Android Stutio当中Webview控件https/http协议的方法
    安卓开发学习笔记(四):Android Stuidio无法实现隐式Intent是为什么?
    XML如何添加注释?
    安卓开发学习笔记(三):Android Stuidio无法引用Intent来创建对象,出现cannot resolve xxx
    安卓开发学习笔记(二):如何用Android Stuidio在res资源下创建xml视图文件
  • 原文地址:https://www.cnblogs.com/softidea/p/4486124.html
Copyright © 2011-2022 走看看