多数据源

下看一下Spring 中如何处理数据源,源代码如下:

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {

    private Map<Object, Object> targetDataSources;

    private Object defaultTargetDataSource;

    private boolean lenientFallback = true;

    private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

    private Map<Object, DataSource> resolvedDataSources;

    private DataSource resolvedDefaultDataSource;

    public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
        this.dataSourceLookup = (dataSourceLookup != null ? dataSourceLookup : new JndiDataSourceLookup());
    }

protected DataSource determineTargetDataSource() {
        Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
        Object lookupKey = determineCurrentLookupKey();
        DataSource dataSource = this.resolvedDataSources.get(lookupKey);
        if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
            dataSource = this.resolvedDefaultDataSource;
        }
        if (dataSource == null) {
            throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
        }
        return dataSource;
    }
    protected abstract Object determineCurrentLookupKey();
}

Spring中的抽象通用数据源类的部分代码,其中包含determineTargetDataSource()方法,调用本类的抽象方法determineCurrentLookupKey(),得到 lookupKey,通过该值设置数据源。所以可以通过继承该类,然后重写该方法实现数据源的切换。

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

import myPath.DataSourceHolder;

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        // TODO Auto-generated method stub
        return DataSourceHolder.getDataSource();  
    }
    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        // TODO Auto-generated method stub
        super.setTargetDataSources(targetDataSources);
    }

}

DataSourceHolder持有当前的数据源,有setter/getter/clear方法

public class DataSourceHolder {
    //线程本地环境
    private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();
    //设置数据源
    public static void setDataSource(String customerType) {
        dataSources.set(customerType);
    }
    //获取数据源
    public static String getDataSource() {
        return (String) dataSources.get();
    }
    //清除数据源
    public static void clearDataSource() {
        dataSources.remove();
    }

}

定义一个注解,使其完成数据源的切换

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataChange {
String value()default "";
}

设置切面和切入点

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import mypath.DataSourceHolder;

@Aspect
@Order(1)
@Component
@Scope("prototype")
public class UseMysql{

@Before("execution(@Class's.Path.DataChange * service.impl.*.*(..))")
    public void dataSourceChange() throws Throwable{
            DataSourceHolder.setDataSource("dataSourcemy");  
            /*这里根据用户的类型来更改对应的数据源*/  
        }  

@After("execution(@Class's.Path.DataChange * service.impl.*.*(..))")
    public void dataSourceclear() throws Throwable{
        DataSourceHolder.clearDataSource();
    }
}

使用

@DataChange
    public Type method(int id) throws IOException {
        return type;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值