springmvc mybatis aop 读写分离 代码实现

关于项目配置,以前的博客都有,我就不多提了,我只发有差异的地方

package com.fileServer.datasource;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;



/**
 * Created by creekhan on 6/13/16.
 */
@Aspect
@Order(value = -9999)
@Component
public class DynamicDataSourceAop {

	private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSourceAop.class);
	
    private static final String[] slaveMethodPreix = {"get", "query", "find", "select", "count","page","isContain","list","check"};
    
    @Before(" execution( * com.fileServer.serviceimpl..*.*(..) ) or  execution( * com.appcore.service.impl.*.*(..) ) ")
    public void checkTransaction(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        if (StringUtils.startsWithAny(methodName, slaveMethodPreix)) {
        	LOGGER.info("当前方法名【{}】切换的数据源【{}】",new Object[] { methodName,"SLAVE"});
        	DynamicDataSourceHolder.setDataSourceKey(DynamicDataSourceHolder.DataSoureKey.SLAVE);	
         } else {
        	LOGGER.info("当前方法名【{}】切换的数据源【{}】",new Object[] { methodName,"MASTER"});
            DynamicDataSourceHolder.setDataSourceKey(DynamicDataSourceHolder.DataSoureKey.MASTER);
        }
    }
    
    
}

package com.fileServer.datasource;



/**
 * Created by creekhan on 6/13/16.
 */
public class DynamicDataSourceHolder {

    private static final ThreadLocal dataSoureThreadLocal = new ThreadLocal<>();

    public static String getDataSourceKey() {
        String persisName = "";
        DataSoureKey dataSoureKey = dataSoureThreadLocal.get();
        if (dataSoureKey == null) {
            persisName = DataSoureKey.MASTER.getKey();
        } else {
            persisName = dataSoureKey.getKey();
        }
        return persisName;
    }

    public static void setDataSourceKey(DataSoureKey dataSource) {
        dataSoureThreadLocal.set(dataSource);
    }


    public static enum DataSoureKey {
        MASTER {
            @Override
            String getKey() {
                return DATASOURCE_MASTER;
            }
        }, SLAVE {
            @Override
            String getKey() {
                return DATASOURCE_SALVE;
            }
        }, ADS {
            @Override
            String getKey() {
                return DATASOURCE_ADS;
            }
        };

        private static final String DATASOURCE_MASTER = "master";
        private static final String DATASOURCE_SALVE = "slave";
        private static final String DATASOURCE_ADS = "ads";

        abstract String getKey();

    }

}

package com.fileServer.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * Created by creekhan on 6/13/16.
 */
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {

        String key = DynamicDataSourceHolder.getDataSourceKey();
        return key;
    }
}



        	
    
	
	
	
	
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    
    
    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    
    
    
        
            
                
                
            
        
    
		
	
springmvc mybatis aop 读写分离 代码实现_第1张图片


springmvc mybatis aop 读写分离 代码实现_第2张图片

核心思路:先初始化多个数据源的bean,然后通过AOP切面切换数据库对应的key(这里一定得用ThreadLocal这个类来对多线程的数据源Key做隔离处理)以及继承AbstractRoutingDataSource来实现多数据源的路由,AOP切面获取joinPoint.getSignature().getName()方法名,再根据自定义的规则做相应的处理。数据库master只允许写入操作,从库只允许读操作,从库和主库在通过mysql 的binLog日志来实现数据同步

你可能感兴趣的:(springmvc,mybatis,Thread,Loca,读写分离代码)