带有ssh隧道的Spring Data JPA到远程MySQL服务器

时间:2015-11-05 14:29:19

标签: java hibernate ssh spring-data jsch

我将Spring Data JPA与Hibernate一起用作持久性提供程序,并与远程MySQL5 Server一起使用,以定期复制内部数据的子集。这项工作(即石英计划的java应用程序)每dai运行一次,需要大约。 30秒完成同步)。出于安全原因,我们不希望打开远程服务器以从外部直接连接(即除localhost之外)。

我已经看到Jsch以编程方式设置ssh隧道的示例,但无法找到有关如何将Jsch与spring数据集成的任何资源。我看到的一个问题是我的某些spring bean(即org.apache.commons.configuration.DatabaseConfiguration)是在应用程序启动时创建的,并且已经需要访问数据源。

我可以在应用程序之外打开ssh隧道,但随后它会一直打开,但我想避免这种情况,因为我只需要每天打开30秒。

编辑:

经过一番研究后,我发现了几种获取ssh隧道的方法

A)实现我自己的DataSource(我扩展了org.springframework.jdbc.datasource.DriverManagerDataSource)然后使用PostContruct和Predestroy来设置/关闭带有Jsch的ssh隧道

- >问题:ssh隧道在应用程序的生命周期内保持打开状态,这不是我想要的

B)实现我自己的驱动程序(我扩展了com.mysql.jdbc.Driver)并覆盖“connect”以在连接之前创建ssh隧道

- >问题:我无法关闭ssh隧道连接

欢迎提出更多建议

1 个答案:

答案 0 :(得分:3)

如果Spring配置中有DataSource bean,则可以创建自己的DataSource实现,在尝试使用提供的JDBC URL建立连接之前打开SSH隧道。例如,请考虑使用HikariDataSource的以下配置:

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource">
    <bean class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">...</bean>
  </property>
</bean>

您可以扩展类HikariDataSource以提供您自己的实现。以下示例:

class TunneledHikariDataSource extends HikariDataSource implements InitializingBean {
  private boolean createTunnel = true;
  private int tunnelPort = 3306;

  public void afterPropertiesSet() {
    if(createTunnel) {
      // 1. Extract remote host name from the JDBC URL.
      // 2. Extract/infer remote tunnel port (e.g. 3306)
      // from the JDBC URL.
      // 3. Create a tunnel using Jsch and sample code
      // at http://www.jcraft.com/jsch/examples/PortForwardingL.java.html
      ...
    }
  }
}

然后,为自定义类而不是HikariDataSource实例化bean实例。