首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring AOP 實現 MySQL 讀寫分離:約定優於配置的優雅方案

     編輯:Java 綜合教學

Spring AOP 實現 MySQL 讀寫分離:約定優於配置的優雅方案

傳統痛點

XML 配置多套 DataSource、SqlSessionFactory、TransactionManager、事務代理,從庫增加時配置膨脹,違背「約定優於配置」。

AOP 方案架構

GitHub:bridgeli/practical-util(cn.bridgeli.datasource 包)

核心組件

  • MasterSlaveDataSource:繼承 AbstractRoutingDataSource,運行期動態切換目標 DataSource。
  • MasterSlaveSelectorByPoll:輪詢策略選擇從庫(支援多從庫負載均衡)。
  • MasterSlaveAspect:@Before 切面,根據方法名前綴決定走主/從庫。

Spring 配置節錄

<!-- 主庫 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource">...</bean>

<!-- 從庫(父子 Bean 復用通用參數) -->
<bean id="parentSlaveDataSource" class="com.alibaba.druid.pool.DruidDataSource" abstract="true">...</bean>
<bean id="slaveDataSource1" parent="parentSlaveDataSource">
  <property name="url" value="${bridgeli_slave1.jdbc.url}"/> ...
</bean>

<!-- 路由 DataSource -->
<bean id="dataSource" class="cn.bridgeli.datasource.MasterSlaveDataSource">
  <property name="targetDataSources">
    <map>
      <entry key-ref="masterDataSource" value-ref="masterDataSource"/>
      <entry key-ref="slaveDataSource1" value-ref="slaveDataSource1"/>
    </map>
  </property>
  <property name="defaultTargetDataSource" ref="masterDataSource"/>
  <property name="masterSlaveSelector" ref="dataSelector"/>
</bean>

<bean id="dataSelector" class="cn.bridgeli.datasource.MasterSlaveSelectorByPoll">
  <property name="masters"><list><ref bean="masterDataSource"/></list></property>
  <property name="slaves"><list><ref bean="slaveDataSource1"/></list></property>
  <property name="defaultDataSource" ref="masterDataSource"/>
</bean>

<!-- AOP 切面:方法名前綴判斷 -->
<bean id="masterSlaveAspect" class="cn.bridgeli.datasource.MasterSlaveAspect">
  <property name="prefixMasters">
    <list><value>save</value><value>update</value><value>delete</value></list>
  </property>
</bean>
<aop:config>
  <aop:aspect id="c" ref="masterSlaveAspect">
    <aop:pointcut id="tx" expression="execution(* cn.bridgeli.service..*.*(..))"/>
    <aop:before pointcut-ref="tx" method="before"/>
  </aop:aspect>
</aop:config>

約定規則

  • Service 方法以 save / update / delete 開頭 → 主庫(寫)。
  • 其餘(get/find/query/list/count 等) → 從庫(讀)。
  • 新增寫操作只需在 prefixMasters 添加前綴,**零代碼侵入**,體現「約定優於配置」。

為什麼切 Service 層?

Service 代表業務邊界,事務天然在這一層;DAO 層無法感知業務讀寫意圖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved