Spring引导AbstractRoutingDataSource

时间:2016-10-13 08:59:20

标签: hibernate spring-boot datasource spring-data-jpa multi-tenant

我正在尝试使用AbstractRoutingDataSource创建动态数据源(基于会话),但是spring boot会在启动时继续调用AbstractRoutingDataSource的determineCurrentLookupKey()函数。

@ConfigurationProperties(prefix = "datasource.int")
@Bean
public DataSource internal() {
    return DataSourceBuilder.create().build();

}

@ConfigurationProperties(prefix = "datasource.ext")
@Bean
public DataSource external() {
    return DataSourceBuilder.create().build();
}

@Bean(name = "dataSource")
@Qualifier("dataSource")
public DynamicRoutingDataSourceResolver dataSource() {
    DynamicRoutingDataSourceResolver resolver = new DynamicRoutingDataSourceResolver();
    DataSource internal = internal();
    DataSource external = external();
    Map<Object, Object> dataSources = new HashMap<>();
    dataSources.put(env.getRequiredProperty("app.param.int"), internal);
    dataSources.put(env.getRequiredProperty("app.param.ext"), external);
    resolver.setDefaultTargetDataSource(internal);
    resolver.setTargetDataSources(dataSources);
    resolver.afterPropertiesSet();

    return resolver;
}

public class DynamicRoutingDataSourceResolver extends  AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {

    HttpServletRequest request = ((ServletRequestAttributes)  RequestContextHolder.getRequestAttributes()).getRequest();
    Object o = request.getSession().getAttribute(Constant.DATASOURCE);
    return o;

}

}

它会抛出NullPointerException,因为RequestAttributes为null。 我试图将@Primary放入其中一个数据源,但是当我尝试执行查询时,没有触发AbstractRoutingDataSource determineCurrentLookupKey()。

我正在使用弹簧数据jpa。

另见session based data source

1 个答案:

答案 0 :(得分:0)

您不必在此处指定任何形式的@Primary

只需创建并将所有数据源分配到AbstractRoutingDataSource即可。如果有一个数据源是默认数据源,也可以使用#setDefaultTargetDataSource进行设置,就像您的代码所示。

您的案例中的NullPointerException只是您的代码需要防范的内容。如果您发现解析程序中不存在请求数据,只需返回数据源查找键的null值即可。

如果返回的查找键是AbstractRoutingDataSource,或者指定的键未通过查找映射定义为数据源,则

null使用定义的默认数据源。