欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2017年01月06日 09:04:06   作者:馳馳的老爸  
本篇文章主要介紹了使用spring aop實現(xiàn)業(yè)務層mysql 讀寫分離,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

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

import java.lang.annotation.ElementType; 
import java.lang.annotation.Target; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
/** 
 * RUNTIME 
 * 編譯器將把注釋記錄在類文件中,在運行時 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.定義一個數(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

<!-- 主庫數(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> 
 
<!-- 從庫數(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, 事務管理 --> 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
  <property name="dataSource" ref="dataSource" /> 
</bean> 
 
 
<!-- 注解自動載入 --> 
<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> 
  
<!-- 激活自動代理功能 --> 
<aop:aspectj-autoproxy proxy-target-class="true"/> 
 
<!-- 配置數(shù)據(jù)庫注解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ù)庫注解aop --> 

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

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

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

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

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

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

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

配置項目依賴的jar,主要是缺少這兩個。

  <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> 

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java對象序列化操作詳解

    Java對象序列化操作詳解

    這篇文章主要介紹了Java對象序列化操作,簡單描述了Java序列化相關(guān)概念、原理并結(jié)合實例形式總結(jié)分析了常見序列化操作相關(guān)定于與使用技巧,需要的朋友可以參考下
    2018-09-09
  • SpringSecurity詳解整合JWT實現(xiàn)全過程

    SpringSecurity詳解整合JWT實現(xiàn)全過程

    JWT作為一個開放的標準(?RFC?7519?),定義了一種簡潔的,自包含的方法用于通信雙方之間以Json對象的形式安全的傳遞信息。接下來通過本文給大家介紹springSecurity+jwt實現(xiàn)互踢功能,需要的朋友可以參考下
    2022-07-07
  • Mybatis中多個對象包含同一個對象的處理操作

    Mybatis中多個對象包含同一個對象的處理操作

    這篇文章主要介紹了Mybatis中多個對象包含同一個對象的處理操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Android讀取本地或網(wǎng)絡圖片并轉(zhuǎn)換為Bitmap

    Android讀取本地或網(wǎng)絡圖片并轉(zhuǎn)換為Bitmap

    這篇文章主要為大家詳細介紹了Android讀取本地或網(wǎng)絡圖片,并轉(zhuǎn)換為Bitmap,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Kotlin中l(wèi)et、run、with、apply及also的用法和差別

    Kotlin中l(wèi)et、run、with、apply及also的用法和差別

    作用域函數(shù)是Kotlin比較重要的一個特性,分為5種let、run、with、apply及also,這五個函數(shù)的工作方式非常相似,但是我們需要了解這5種函數(shù)的差異,以便在不同的場景更好的利用它,這篇文章主要介紹了Kotlin中l(wèi)et、run、with、apply及also的差別,需要的朋友可以參考下
    2023-11-11
  • Java環(huán)境配置原理全面解析

    Java環(huán)境配置原理全面解析

    下面小編就為大家?guī)硪黄狫ava環(huán)境配置原理全面解析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • SpringBoot單元測試框架Mockito介紹及使用

    SpringBoot單元測試框架Mockito介紹及使用

    與集成測試將系統(tǒng)作為一個整體測試不同,單元測試更應該專注于某個類。所以當被測試類與外部類有依賴的時候,尤其是與數(shù)據(jù)庫相關(guān)的這種費時且有狀態(tài)的類,很難做單元測試。但好在可以通過“Mockito”這種仿真框架來模擬這些比較費時的類,從而專注于測試某個類內(nèi)部的邏輯
    2023-01-01
  • Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例

    Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例

    spring提供的定時發(fā)送郵件功能一直深受廣大web開發(fā)者的喜愛,這篇文章主要介紹了Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例,有興趣的可以了解一下。
    2017-03-03
  • SpringBoot如何通過自定義注解實現(xiàn)權(quán)限檢查詳解

    SpringBoot如何通過自定義注解實現(xiàn)權(quán)限檢查詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot如何通過自定義注解實現(xiàn)權(quán)限檢查的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • Java關(guān)鍵字synchronized原理與鎖的狀態(tài)詳解

    Java關(guān)鍵字synchronized原理與鎖的狀態(tài)詳解

    在Java當中synchronized關(guān)鍵字通常是用來標記一個方法或者代碼塊。本文將通過示例為大家詳細介紹一下Synchronized的各種使用方法,需要的可以參考一下
    2022-08-08

最新評論