欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多数据源

程序员文章站 2022-07-15 10:10:38
...

下看一下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;
    }

上一篇: 多数据源

下一篇: 多数据源补充