覆盖默认数据源 getConnection()
Posted
技术标签:
【中文标题】覆盖默认数据源 getConnection()【英文标题】:Override Default Datasource getConnection() 【发布时间】:2017-07-07 21:49:54 【问题描述】:我正在尝试将 Spring 应用程序(大部分)转换为 Spring Boot 应用程序。在应用程序中,我有一个 HTTP 基本过滤器,用于收集用户名和密码,然后在 DataSource 实现中作为变量传递。
在这个DataSource中,getConnection()方法是这样的:
@Override\n public Connection getConnection() throws SQLException
Statement stmt = null;
try
ConnectionWrapper connection = this.authenticatedConnection.get();
if (connection == null)
connection = new ConnectionWrapper(this.dataSource.getConnection());
StringBuilder command;
// The CONNECT command allows indicating a user name, a password
// and a database to initiate a
// new session in the server with a new profile.
command = new StringBuilder("CONNECT USER ").append(this.parameters.get().get(USER_NAME)).append(" PASSWORD ")
.append("'").append(this.parameters.get().get(PASSWORD_NAME)).append("'").append(" DATABASE ")
.append(this.parameters.get().get(DATA_BASE_NAME));
this.authenticatedConnection.set(connection);
stmt = connection.createStatement();
stmt.execute(command.toString());
return connection;
catch (final SQLException e) ...`
(由于 *** 格式问题,使用 \n 作为新行)
在 Spring 中,我可以毫无问题地实现 @Autowired Private DataSource dataSource。在 Spring Boot 中,据我了解,Object 需要是一个 Bean 才能使用 @Autowired,但是当我在实现 DataSource 之前添加 @Bean 时,我得到“该位置不允许使用 @Bean 注释”
我怎样才能得到它,以便我可以做一个 dataSource.getConnection();并从主数据源获取连接,或者能够覆盖主数据源的方法?
在我看来,这里按优先顺序列出了 4 种可能的解决方案:
-
创建一个实际上覆盖 spring.datasource 方法的 DataSource。
将此实现“Beanified”,这样我就可以再次 @Autowired 数据源。
我想我可以跳过 @Autowired 并简单地设置 this.dataSource = [unknown reference to spring.datasource defined in application.properties]
创建另一个DataSource类ProgrammedDataSource,配置spring.datasource属性,然后设置为this.dataSource = new ProgrammedDataSource();
但我在实施任何这些解决方案的尝试都产生了这个问题。
【问题讨论】:
你了解可以用来指示类是 Spring bean 的各种构造型注释(这是一个提示)吗? 感谢更多 Google 搜索。 我已将其范围缩小到 @Repository 注释。我现在正在研究它,当我开始工作时会提供答案。 (如果没有其他人做出可接受的回应。) 不管我如何尝试来自@Autowired private DataSource dataSource 的 this.dataSource;一片空白。 application.properties 设置正确。 有很多关于如何使用 Java 配置创建DataSource
的示例。
【参考方案1】:
我想通了。我不需要在那里制作 Bean,尽管我仍然不确定为什么不允许我在 DataSource 之前调用 @Bean,但无论如何。
在我拥有的应用程序中:
public class ServiceApplication
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource dataSource()
return DataSourceBuilder.create().build();
@Bean(name="AuthDataSource")
public DataSource authDataSource()
return new AuthDataSource();
public static void main(String[] args)
SpringApplication.run(ServiceApplication.class, args);
在我拥有的控制器中:
@Controller
@RequestMapping("/service")
public class ServiceController
@Autowired
public void MyBean(JdbcTemplate jdbcTemplate)
this.jdbcTemplate = new JdbcTemplate(new AuthDataSource());
...
但是,由于我在该 JdbcTemplate 中调用了 new AuthDataSource(),因此它没有执行自动装配。现在控制器看起来像这样并且它可以工作:
@Controller
@RequestMapping("/service")
public class ServiceController
@Autowired
@Qualifier("AuthDataSource")
private DataSource datasource;
private JdbcTemplate jdbcTemplate;
@Autowired
public void MyBean(JdbcTemplate jdbcTemplate)
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
...
【讨论】:
以上是关于覆盖默认数据源 getConnection()的主要内容,如果未能解决你的问题,请参考以下文章
如果重写setUp和tearDown,则不会调用PHP,phpunit和dbunit - getConnection和getDataSet
为 jdbc 数据直接 sqlserver 驱动程序覆盖 org.apache.solr.handler.dataimport.JdbcDataSource