覆盖默认数据源 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()的主要内容,如果未能解决你的问题,请参考以下文章

覆盖rails3中模型名称的默认复数

我的材质 UI 自定义类被材质 UI 的默认类覆盖

Spring事务

如果重写setUp和tearDown,则不会调用PHP,phpunit和dbunit - getConnection和getDataSet

为 jdbc 数据直接 sqlserver 驱动程序覆盖 org.apache.solr.handler.dataimport.JdbcDataSource

ExtJS - 覆盖默认存储数据