文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java基于JNDI怎么实现读写分离

2023-06-22 01:49

关注

这篇文章主要介绍“Java基于JNDI怎么实现读写分离”,在日常操作中,相信很多人在Java基于JNDI怎么实现读写分离问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java基于JNDI怎么实现读写分离”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、JNDI数据源配置

在Tomcat的conf目录下,context.xml在其中标签中添加如下JNDI配置:

<Resource name="dataSourceMaster" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"  auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWaitMillis="30000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver"  url="jdbc:mysql://localhost:3306/user_master?useUnicode=true&amp;characterEncoding=utf-8"/><Resource name="dataSourceSlave" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"  auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWaitMillis="30000"    username="root" password="root" driverClassName="com.mysql.jdbc.Driver"  url="jdbc:mysql://localhost:3306/user_slave?useUnicode=true&amp;characterEncoding=utf-8"/>

二、JNDI数据源使用

在普通web项目中

(1)在web.xml文件中添加如下配置(也可以不配置):

<resource-ref> <res-ref-name>dataSourceMaster</res-ref-name> <res-type>javax.sql.DataSource</res-type>  <res-auth>Container</res-auth></resource-ref><resource-ref> <res-ref-name>dataSourceSlave</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth></resource-ref>

三、web.xml配置

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app>   <display-name>Archetype Created Web Application</display-name>   <context-param>      <param-name>log4jConfigLocation</param-name>      <param-value>classpath:log4j.properties</param-value>   </context-param>     <context-param>      <param-name>log4jRefreshInterval</param-name>      <param-value>60000</param-value>   </context-param>   <filter>      <filter-name>CharacterEncodingFilter</filter-name>      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>       <init-param>         <param-name>encoding</param-name>         <param-value>utf-8</param-value>      </init-param>      <init-param>         <param-name>forceEncoding</param-name>         <param-value>true</param-value>      </init-param>   </filter>   <filter-mapping>      <filter-name>CharacterEncodingFilter</filter-name>      <servlet-name>xiyun</servlet-name>   </filter-mapping>   <servlet>      <servlet-name>xiyun</servlet-name>      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>      <init-param>         <param-name>contextConfigLocation</param-name>         <param-value>        classpath:conf/spring/spring-servlet.xml      </param-value>      </init-param>      <load-on-startup>1</load-on-startup>   </servlet>   <servlet-mapping>      <servlet-name>xiyun</servlet-name>      <url-pattern>*.do</url-pattern>   </servlet-mapping></web-app>

四、spring-servlet.xml配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">      <context:component-scan base-package="com.xiaoxi"/>      <mvc:annotation-driven/>      <import resource="classpath:conf/spring/spring-db.xml"/>      <bean id="viewResolver"          class="org.springframework.web.servlet.view.InternalResourceViewResolver">          <property name="prefix" value="/WEB-INF/freemarker/"/>          <property name="suffix" value=".ftl"/>      </bean> </beans>

五、spring-db.xml配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" >      <!-- 主数据源配置 -->     <bean id="dataSourceMaster" class="org.springframework.jndi.JndiObjectFactoryBean">          <property name="jndiName" value="java:comp/env/dataSourceMaster"/>     </bean>     <!-- 从数据源配置 -->     <bean id="dataSourceSlave" class="org.springframework.jndi.JndiObjectFactoryBean">          <property name="jndiName" value="java:comp/env/dataSourceSlave"/>     </bean>      <aop:aspectj-autoproxy proxy-target-class="true"/>        <context:annotation-config/>     <bean id="dynamicDataSource" class="com.xiaoxi.config.DynamicRoutingDataSource">          <property name="targetDataSources">               <map>                    <entry key="Master" value-ref="dataSourceMaster"/>                    <entry key="Slave" value-ref="dataSourceSlave"/>               </map>          </property>          <property name="defaultTargetDataSource" value="dataSourceMaster"/>     </bean>      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">          <!-- 配置数据源 -->          <property name="dataSource" ref="dynamicDataSource"/>     </bean>      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">          <!-- 映射数据源 -->          <property name="dataSource" ref="dynamicDataSource"/>          <!-- 映射mybatis核心配置文件 -->          <property name="configLocation" value="classpath:conf/spring/mybatis-config.xml"/>          <!-- 映射mapper文件 -->          <property name="mapperLocations">               <list>                    <value>classpath:conf/sqlMappublic class DataSourceContextHolder {    private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<>();    public static ThreadLocal<DbType> getLocal() {        return contextHolder;    }    private DataSourceContextHolder () {}    public static String getDbType() {        return contextHolder.get() == null ? DbType.MASTER.dbType : contextHolder.get().dbType;    }    public static void setDbType(DbType dbType) {        contextHolder.set(dbType);    }    public static void clearDbType() {        contextHolder.remove();    }    public enum DbType {        MASTER("Master"),        SLAVE("Slave");        private String dbType;        DbType(String dbType) {            this.dbType = dbType;        }        public String getDbType() {            return dbType;        }    }}
package com.xiaoxi.aop;import com.xiaoxi.config.DataSourceContextHolder;import org.apache.log4j.Logger;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Aspect@Order(-1)@Componentpublic class DataSourceAop {    private static Logger logger = Logger.getLogger(DataSourceAop.class);    @Before("execution(* com.xiaoxi.dao..*.query*(..))")    public void setReadDataSourceType() {        DataSourceContextHolder.setDbType(DataSourceContextHolder.DbType.MASTER);        logger.debug("[DataSourceAop] DataSource Covert To SLAVE");    }    @Before("execution(* com.xiaoxi.dao..*.insert*(..))" +         "|| execution(* com.xiaoxi.dao..*.update*(..))" +         "|| execution(* com.xiaoxi.dao..*.delete*(..))")    public void setWriteDataSourceType() {        DataSourceContextHolder.setDbType(DataSourceContextHolder.DbType.SLAVE);        logger.debug("[DataSourceAop] DataSource Covert To MASTER");    }        @Pointcut("execution(* com.xiaoxi.dao..*.*(..))")    public void cutPoint() {}    @Before(value="cutPoint()")    public void setDynamicDataSource(JoinPoint point){        String className = point.getTarget().getClass().getSimpleName();        String methodName = point.getSignature().getName();        String log = "[DataSourceAop] className:%s, methodName:%s";        logger.debug(String.format(log, className, methodName));    }}

八、搭建过程中遇到的问题和解决方案

注入数据源dataSourceMaster和dataSourceSlave失败
spring 中jndiName配置的数据源名称和Tomcat配置文件中Resource name存在区别,并非一致,其中java:comp/env为环境,否则会报can not find jndi name …

Cannot create JDBC driver of class ‘' for connect URL ‘null'

The requested resource is not available(404)
分析了web.xml和servlet.xml发现配置无误,注解驱动和包扫描都配置,但仍然访问不了,后发现
项目启动过程中打印的日志存在问题,如下:
2019-12-17 16:20:41,767 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping- Mapped “{[/userInfo],methods=[GET]}” onto public java.lang.String com.xiaoxi.controller.UserInfoController.queryUserInfoById(java.lang.String)
通过分析发现这里的请求映射,通过controller的requestMapping映射到具体方法,却丢失了方法上的requestMapping路径,后发现方法RequestMapping写法如下:

@Controller@RequestMapping("/userInfo")public class UserInfoController {    private static Logger logger =Logger.getLogger(UserInfoController.class);    @Autowired    private UserInfoService userInfoService;    @ResponseBody    @RequestMapping(name= "/queryUserInfoById", method = RequestMethod.GET)    public String queryUserInfoById(@RequestParam("id") String id){        logger.info("UserInfoController.queryUserInfoById.  id:{}" + id);        UserInfo userInfo = userInfoService.queryUserInfoById(id);        return JSON.toJSONString(userInfo);    }}

此处的RequestMapping属性name应该改为value,否则解析为空(可查看注解定义)

到此,关于“Java基于JNDI怎么实现读写分离”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯