国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

詳解使用spring aop實(shí)現(xiàn)業(yè)務(wù)層mysql 讀寫分離

2019-11-26 13:18:39
字體:
供稿:網(wǎng)友

spring aop , mysql 主從配置 實(shí)現(xiàn)讀寫分離,接下來把自己的配置過程,以及遇到的問題記錄下來,方便下次操作,也希望給一些朋友帶來幫助。

1.使用spring aop 攔截機(jī)制現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)選取。

import java.lang.annotation.ElementType; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /**  * RUNTIME  * 編譯器將把注釋記錄在類文件中,在運(yùn)行時(shí) VM 將保留注釋,因此可以反射性地讀取。  * @author yangGuang  *  */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource {   String value(); } 

3.利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;   public class ChooseDataSource extends AbstractRoutingDataSource {     @Override    protected Object determineCurrentLookupKey() {      return HandleDataSource.getDataSource();    }      } 

4.利用ThreadLocal解決線程安全問題

public class HandleDataSource {   public static final ThreadLocal<String> holder = new ThreadLocal<String>();   public static void putDataSource(String datasource) {     holder.set(datasource);   }      public static String getDataSource() {     return holder.get();   }   } 

5.定義一個(gè)數(shù)據(jù)源切面類,通過aop訪問,在spring配置文件中配置了,所以沒有使用aop注解。

import java.lang.reflect.Method; 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.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; //@Aspect //@Component public class DataSourceAspect {   //@Pointcut("execution(* com.apc.cms.service.*.*(..))")    public void pointCut(){};      // @Before(value = "pointCut()")    public void before(JoinPoint point)     {       Object target = point.getTarget();       System.out.println(target.toString());       String method = point.getSignature().getName();       System.out.println(method);       Class<?>[] classz = target.getClass().getInterfaces();       Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())           .getMethod().getParameterTypes();       try {         Method m = classz[0].getMethod(method, parameterTypes);         System.out.println(m.getName());         if (m != null && m.isAnnotationPresent(DataSource.class)) {           DataSource data = m.getAnnotation(DataSource.class);           HandleDataSource.putDataSource(data.value());         }                } catch (Exception e) {         e.printStackTrace();       }     } } 

6.配置applicationContext.xml

<!-- 主庫(kù)數(shù)據(jù)源 -->  <bean id="writeDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">   <property name="driverClass" value="com.mysql.jdbc.Driver"/>   <property name="jdbcUrl" value="jdbc:mysql://172.22.14.6:3306/cpp?autoReconnect=true"/>   <property name="username" value="root"/>   <property name="password" value="root"/>   <property name="partitionCount" value="4"/>   <property name="releaseHelperThreads" value="3"/>   <property name="acquireIncrement" value="2"/>   <property name="maxConnectionsPerPartition" value="40"/>   <property name="minConnectionsPerPartition" value="20"/>   <property name="idleMaxAgeInSeconds" value="60"/>   <property name="idleConnectionTestPeriodInSeconds" value="60"/>   <property name="poolAvailabilityThreshold" value="5"/> </bean>  <!-- 從庫(kù)數(shù)據(jù)源 --> <bean id="readDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">   <property name="driverClass" value="com.mysql.jdbc.Driver"/>   <property name="jdbcUrl" value="jdbc:mysql://172.22.14.7:3306/cpp?autoReconnect=true"/>   <property name="username" value="root"/>   <property name="password" value="root"/>   <property name="partitionCount" value="4"/>   <property name="releaseHelperThreads" value="3"/>   <property name="acquireIncrement" value="2"/>   <property name="maxConnectionsPerPartition" value="40"/>   <property name="minConnectionsPerPartition" value="20"/>   <property name="idleMaxAgeInSeconds" value="60"/>   <property name="idleConnectionTestPeriodInSeconds" value="60"/>   <property name="poolAvailabilityThreshold" value="5"/> </bean>  <!-- transaction manager, 事務(wù)管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   <property name="dataSource" ref="dataSource" /> </bean>   <!-- 注解自動(dòng)載入 --> <context:annotation-config />  <!--enale component scanning (beware that this does not enable mapper scanning!)--> <context:component-scan base-package="com.apc.cms.persistence.rdbms" /> <context:component-scan base-package="com.apc.cms.service">  <context:include-filter type="annotation"      expression="org.springframework.stereotype.Component" />  </context:component-scan>   <context:component-scan base-package="com.apc.cms.auth" />  <!-- enable transaction demarcation with annotations --> <tx:annotation-driven />   <!-- define the SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">   <property name="dataSource" ref="dataSource" />   <property name="typeAliasesPackage" value="com.apc.cms.model.domain" /> </bean>  <!-- scan for mappers and let them be autowired --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">   <property name="basePackage" value="com.apc.cms.persistence" />   <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>  <bean id="dataSource" class="com.apc.cms.utils.ChooseDataSource">   <property name="targetDataSources">       <map key-type="java.lang.String">         <!-- write -->        <entry key="write" value-ref="writeDataSource"/>         <!-- read -->        <entry key="read" value-ref="readDataSource"/>       </map>          </property>    <property name="defaultTargetDataSource" ref="writeDataSource"/>  </bean>   <!-- 激活自動(dòng)代理功能 --> <aop:aspectj-autoproxy proxy-target-class="true"/>  <!-- 配置數(shù)據(jù)庫(kù)注解aop --> <bean id="dataSourceAspect" class="com.apc.cms.utils.DataSourceAspect" /> <aop:config>   <aop:aspect id="c" ref="dataSourceAspect">     <aop:pointcut id="tx" expression="execution(* com.apc.cms.service..*.*(..))"/>     <aop:before pointcut-ref="tx" method="before"/>   </aop:aspect> </aop:config> <!-- 配置數(shù)據(jù)庫(kù)注解aop --> 

7.使用注解,動(dòng)態(tài)選擇數(shù)據(jù)源,分別走讀庫(kù)和寫庫(kù)。

@DataSource("write") public void update(User user) {   userMapper.update(user); }  @DataSource("read") public Document getDocById(long id) {   return documentMapper.getById(id); } 

測(cè)試寫操作:可以通過應(yīng)用修改數(shù)據(jù),修改主庫(kù)數(shù)據(jù),發(fā)現(xiàn)從庫(kù)的數(shù)據(jù)被同步更新了,所以定義的write操作都是走的寫庫(kù)

測(cè)試讀操作:  后臺(tái)修改從庫(kù)數(shù)據(jù),查看主庫(kù)的數(shù)據(jù)沒有被修改,在應(yīng)用頁(yè)面中刷新,發(fā)現(xiàn)讀的是從庫(kù)的數(shù)據(jù),說明讀寫分離ok。

遇到的問題總結(jié):

問題1:項(xiàng)目是maven工程,用到了Spring aop機(jī)制,除了spring的核心jar包以為,還需要用到的jar包有aspectj.jar,aspectjweaver.jar,aopalliance.jar查看項(xiàng)目中的pom,發(fā)現(xiàn)缺少依賴包,由于本地倉(cāng)庫(kù)沒有這些jar,查找可以提供下載jar包的maven中央庫(kù)庫(kù),配置到maven中,自動(dòng)更新:

<repository>    <id>nexus</id>    <name>nexus</name>    <url>http://repository.sonatype.org/content/groups/public/</url>    <layout>default</layout>  </repository> 

配置項(xiàng)目依賴的jar,主要是缺少這兩個(gè)。

  <dependency>     <groupId>aspectj</groupId>     <artifactId>aspectjrt</artifactId>     <version>1.5.4</version> </dependency> <dependency>     <groupId>aspectj</groupId>     <artifactId>aspectjweaver</artifactId>     <version>1.5.4</version> lt;/dependency> 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 瑞金市| 板桥市| 仲巴县| 黄平县| 潞城市| 台州市| 牡丹江市| 张北县| 万山特区| 石柱| 普宁市| 黔西| 高雄市| 额济纳旗| 伊春市| 甘泉县| 迭部县| 雷波县| 依安县| 福海县| 康定县| 慈溪市| 长寿区| 敖汉旗| 巢湖市| 衢州市| 永年县| 桓仁| 任丘市| 兴安盟| 黄陵县| 襄樊市| 甘泉县| 策勒县| 巴楚县| 新蔡县| 赞皇县| 海城市| 驻马店市| 巧家县| 防城港市|