Spring中的动态数据源连接

时间:2017-06-07 10:25:33

标签: java database spring

当我的应用程序启动时,它会创建一个数据库的连接。在运行时,我在同一个数据库服务器中获取了其他数据库名如何在运行时为其他数据库创建连接?目前我正在传递dbNameto方法,如:

@Bean
@Scope("prototype")
public DataSource getDataSource(String dbName) {

    String dbUrl = DATABASE_JDBC_URL + dbName;

    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(DRIVER_CLASS_NAME);
    dataSource.setUrl(dbUrl);
    dataSource.setUsername(DATABASE_USERNAME);
    dataSource.setPassword(DATABASE_PASSWORD);

    return dataSource;
}

当我在上面的@Bean getDataSource(String dbName)方法中传递参数 dbName 时,我得到了以下异常

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)

2 个答案:

答案 0 :(得分:0)

您可以在Datasource周围创建一个包装器,如:

@Component
public class DataSourceManager implements DataSource{

    private DataSource dataSource;

    @PostConstruct
    public void init() {
        // init the datasource
    }

    public DataSource getDataSource(String dbName) {
        return dataSource;
    }

    public void switchDataSource(String name) {
        // re init the datasource
    }

    @Override
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    .... wrap all the other DataSource methods

}

答案 1 :(得分:0)

创建一个新的Singleton范围bean

@Bean
public DBName getDBName(){
    return new DBName();
 }

并通过每次需要新数据库连接时将数据库名称设置为datasource bean来传递此bean

@Bean
@Scope("prototype")
public DataSource getDataSource(DBName dbNameObj) {
...

}

DBName类可以写成

public class DBName {

    private String dbName;

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }