Mastering Database Read/Write Splitting with Spring AOP: A Practical Demo

This article explains the concept of read/write splitting in distributed databases, outlines two implementation methods—static dual data sources and dynamic AOP-based switching—provides a complete Spring‑MyBatis demo with configuration files, code snippets, and guidance on setting up master and slave connections.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Mastering Database Read/Write Splitting with Spring AOP: A Practical Demo

Introduction

Read/write splitting in a distributed environment is a key solution to database read/write performance bottlenecks, greatly improving read speed and concurrency.

To achieve it, a master‑slave configuration is required. The simplest setup uses one Master and one Slave; reads go to the Slave, writes to the Master, reducing load on a single server.

Two Implementation Methods

Method 1: Define two data sources, MasterDataSource for writes and SlaveDataSource for reads. The application explicitly selects the appropriate source.

Method 2: Dynamic data‑source switching using AOP. At runtime the program weaves the data source based on the invoked method, leveraging annotations, Spring AOP and reflection.

AOP‑Based Read/Write Splitting Demo

Project code is available at the open‑source repository:

http://git.oschina.net/xuliugen/aop-choose-db-demo

Key components include:

ChooseDataSource – selects the appropriate data source.

DataSourceAspect – intercepts methods to determine read or write operations.

DataSourceHandler – handles the actual data‑source routing.

Configuration files (Spring XML) define readDataSource, writeDataSource, and a dynamic dataSource bean that references ChooseDataSource. The XML snippet is shown below:

<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"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true">
        <property name="logSlowSql" value="true"/>
        <property name="mergeSql" value="true"/>
    </bean>

    <!-- read data source -->
    <bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close" init-method="init" lazy-init="true">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url1}"/>
        <property name="username" value="root"/>
        <property name="password" value="${password}"/>
    </bean>

    <!-- write data source -->
    <bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close" init-method="init" lazy-init="true">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="root"/>
        <property name="password" value="${password}"/>
    </bean>

    <!-- dynamic routing data source -->
    <bean id="dataSource" class="com.xuliugen.choosedb.demo.aspect.ChooseDataSource" lazy-init="true">
        <property name="targetDataSources">
            <map key-type="java.lang.String" value-type="javax.sql.DataSource">
                <entry key="write" value-ref="writeDataSource"/>
                <entry key="read" value-ref="readDataSource"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="writeDataSource"/>
        <property name="methodType">
            <map key-type="java.lang.String">
                <entry key="read" value=",get,select,count,list,query"/>
                <entry key="write" value=",add,create,update,delete,remove,"/>
            </map>
        </property>
    </bean>
</beans>

The demo uses the SSM framework (Spring, Spring MVC, MyBatis). The UserController simulates read/write operations by invoking IUserService. Diagrams illustrate the project structure and the flow of AOP‑based data‑source selection.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaMaster‑SlaveMyBatisread/write splittingspring-aopDatabase Replication
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.