spring配置动态数据源

第一通过环绕通知控制某些方法应用master-datasource,某些方法应用slave-datasource
package com.demo.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.demo.datasource.DynamicDataSource;

public class DataSourceAspect implements MethodInterceptor{

	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO Auto-generated method stub
		try {
			String method = invocation.getMethod().getName();
			if (method.startsWith("add") || method.startsWith("update") || method.startsWith("delete")) {
				DynamicDataSource.useMaster();
			} else {
				DynamicDataSource.useSlave();
			}
			return invocation.proceed();
		} catch (Exception ex) {
			throw ex;
		} finally {
			DynamicDataSource.reset();
		}
		
	}

}
第二编写动态数据源
package com.demo.datasource;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {
	private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);
	private DataSource master; // 主库,只允许有一个
    private List slaves; // 从库,允许有多个
    private AtomicLong slaveCount = new AtomicLong();
    private int slaveSize = 0;

    private Map dataSources = new HashMap();

    private static final String DEFAULT = "master";
    private static final String SLAVE = "slave";

    private static final ThreadLocal> datasourceHolder = new ThreadLocal>() {

        @Override
        protected LinkedList initialValue() {
            return new LinkedList();
        }

    };
    /**
     * 初始化
     */
    @Override
    public void afterPropertiesSet() {
        if (null == master) {
            throw new IllegalArgumentException("Property 'master' is required");
        }
        dataSources.put(DEFAULT, master);
        if (null != slaves && slaves.size() > 0) {
            for (int i = 0; i < slaves.size(); i++) {
                dataSources.put(SLAVE + (i + 1), slaves.get(i));
            }
            slaveSize = slaves.size();
        }
        this.setDefaultTargetDataSource(master);
        this.setTargetDataSources(dataSources);
        super.afterPropertiesSet();
    }
    /**
     * 选择使用主库,并把选择放到当前ThreadLocal的栈顶
     */
    public static void useMaster() {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("use datasource :" + datasourceHolder.get());
        }
        LinkedList m = datasourceHolder.get();
        m.offerFirst(DEFAULT);
    }

    /**
     * 选择使用从库,并把选择放到当前ThreadLocal的栈顶
     */
    public static void useSlave() {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("use datasource :" + datasourceHolder.get());
        }
        LinkedList m = datasourceHolder.get();
        m.offerFirst(SLAVE);
    }

    /**
     * 重置当前栈
     */
    public static void reset() {
        LinkedList m = datasourceHolder.get();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("reset datasource {}", m);
        }
        if (m.size() > 0) {
            m.poll();
        }
    }

	@Override
	protected Object determineCurrentLookupKey() {
		// TODO Auto-generated method stub
		LinkedList m = datasourceHolder.get();
        String key = m.peekFirst() == null ? "" : m.peekFirst();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("currenty datasource :" + key);
        }
        if (null != key) {
            if (DEFAULT.equals(key)) {
                return key;
            } else if (SLAVE.equals(key)) {
                if (slaveSize > 1) {// Slave loadBalance
                    long c = slaveCount.incrementAndGet();
                    c = c % slaveSize;
                    return SLAVE + (c + 1);
                } else {
                    return SLAVE + "1";
                }
            }
            return null;
        } else {
            return null;
        }
	}
	public DataSource getMaster() {
        return master;
    }

    public List getSlaves() {
        return slaves;
    }

    public void setMaster(DataSource master) {
        this.master = master;
    }

    public void setSlaves(List slaves) {
        this.slaves = slaves;
    }
}
第三修改spring配置文件

	
		 
         
         
         
         
         
         
         
         
	
    
    
        
        
        
        
    
    
    
        
        
        
        
    
    
        
        
            
               
            
        
    

	
		
	

	
	

	
	
		
			
			
			

			
			
		
	
	
	
	
		
		
		
	

你可能感兴趣的:(java)