zoukankan      html  css  js  c++  java
  • Spring aop读写分离

    一、采用读写分离技术的目标

           随着网站的业务不断扩展,数据不断增加,用户越来越多,数据库的压力也就越来越大,采用传统的方式,比如:数据库或者SQL的优化基本已达不到要求,这个时候可以采用读写分离的策略来改变现状。采用读写分离技术能够有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。

    二、常用的两种方式

        1、定义两个数据库链接,一个是masterDataSource,另个是slaveDataSource,更新数据时读取masterDataSource,查询是读取slaveDataSource。

         2、动态数据源切换,在程序运行时,把数据源动态织如入程序中,从而选择主库还是从库。主要技术采用annotation,Spring AOP,反射,接下来详细介绍该种方法。

    三、动态数据源切换实现读写分离

     1,定义DataSource注解

    @Retention(RetentionPolicy.RUNTIME)  

    @Target(ElementType.METHOD)

    public @interface DataSource {

     String value(); 

    }

    2,继承抽象类AbstractRoutingDataSource来实现DynamicDataSource方法 

    public class DynamicDataSource extends AbstractRoutingDataSource{ 

     public static final Logger logger = Logger.getLogger(DynamicDataSource.class.toString()); 

     @Override

        protected Object determineCurrentLookupKey() {

             return DynamicDataSourceHolder.getDataSource();

        }

    }

    3,定义DynamicDataSourceHolder方法

     public class DynamicDataSourceHolder {

      private static final ThreadLocal<String> holder = new ThreadLocal<String>();

         public static void setDataSource(String name) {

             holder.set(name);

         }

         public static String getDataSource() {

             return holder.get();

         }  

    }

    4,定义DataSourceAspect类,在程序运行时动态切换数据源

    public class DataSourceAspect {  

        public void before(JoinPoint point){  

            Object target = point.getTarget();   

            String method = point.getSignature().getName();   

            Class<?>[] classz = target.getClass().getInterfaces();  

            Class<?>[] parameterTypes = ((MethodSignature)point.getSignature()).getParameterTypes();  

            try{  

                Method m = classz[0].getMethod(method, parameterTypes);  

                if(m != null && m.isAnnotationPresent(DataSource.class)){  

                    DataSource date = m.getAnnotation(DataSource.class);  

                    DynamicDataSourceHolder.setDataSource(date.value());  

                }  

                else {

                    // 默认master

                    DynamicDataSourceHolder.setDataSource("master");

                }

            }catch(Exception e){               

            }  

        }  

    }

    5,applicationContext-dataSource.xml配置

      分别定义主从数据源后,再添加选择数据源的bean

    <bean id="dataSource" class="****">

     <property name="targetDataSources">

     <map key-type="java.lang.String">

     <entry key="master" value-ref="masterDataSource"/>

     <entry key="slave" value-ref="slaveDataSource"/>

       </map>

     </property>

     <property name="defaultTargetDataSource" ref="masterDataSource"/>

     </bean>

    增加aop配置

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>      <bean id="manyDataSourceAspect" class="****.DataSourceAspect" />  

        <aop:config>  

            <aop:aspect id="c" ref="manyDataSourceAspect">  

                <aop:before method="before" pointcut="execution(* *****.data.dao.*.*(..))"></aop:before>  

            </aop:aspect>  

        </aop:config>  

    6,DAO层定义方法的数据源

    @DataSource(value="slave")

     public ImUser findById(int id);

  • 相关阅读:
    都在谈零信任,网络安全和零信任架构的核心是什么?
    盘点:区块链有望被主流接纳的四个场景
    同态加密:密码学的下一个黄金时代
    浅谈人工智能应对数字化转型挑战的5个领域
    2021年7项物联网预测
    15分钟=1年!当人工智能遇到材料学……
    人工智能推理的演进
    保护加密货币资产的7种优秀做法
    ES6语法 Promise Iterator
    css阴影框
  • 原文地址:https://www.cnblogs.com/jiangxiaoyaoblog/p/5600814.html
Copyright © 2011-2022 走看看