亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用spring aop實現業務層mysql讀寫分離

發布時間:2021-09-16 16:34:38 來源:億速云 閱讀:112 作者:chen 欄目:云計算

本篇內容主要講解“如何使用spring aop實現業務層mysql讀寫分離”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何使用spring aop實現業務層mysql讀寫分離”吧!

1.使用spring aop 攔截機制現數據源的動態選取。

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解決多數據源的問題 參考: http://blog.csdn.net/alaahong/article/details/8707915

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.定義一個數據源切面類,通過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

<!-- 主庫數據源 -->
     <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>
    
    <!-- 從庫數據源 -->
    <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"/>
    
    <!-- 配置數據庫注解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>
    <!-- 配置數據庫注解aop -->



    
7.使用注解,動態選擇數據源,分別走讀庫和寫庫。

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


測試寫操作:可以通過應用修改數據,修改主庫數據,發現從庫的數據被同步更新了,所以定義的write操作都是走的寫庫

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

 
遇到的問題總結:

  問題1:項目是maven工程,用到了Spring aop機制,除了spring的核心jar包以為,還需要用到的jar包有aspectj.jar,aspectjweaver.jar,aopalliance.jar查看項目中的pom,發現缺少依賴包,
    由于本地倉庫沒有這些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>
        </dependency>

到此,相信大家對“如何使用spring aop實現業務層mysql讀寫分離”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东港市| 肃宁县| 桂东县| 福建省| 饶河县| 宁晋县| 鲁甸县| 曲阜市| 金寨县| 城固县| 探索| 华安县| 承德县| 宝坻区| 聂拉木县| 铅山县| 察隅县| 阿坝| 田林县| 静乐县| 曲沃县| 专栏| 阜新市| 涟源市| 嵩明县| 吉木萨尔县| 二手房| 庆阳市| 河源市| 耒阳市| 临西县| 新津县| 岑溪市| 马公市| 崇阳县| 奇台县| 白银市| 博湖县| 商河县| 江永县| 怀柔区|