2015-11-05 131 views
1

我正在使用Spring Data JPA与Hibernate作为持久性提供程序与远程MySQL5服务器一起工作,以定期复制内部数据的子集。这项工作(即石英计划的Java应用程序)每个运行一次,需要大约一次。 30秒以完成同步)。出于安全原因,我们不希望打开远程服务器以便从外部直接连接(即,不是本地主机)。Spring数据JPA与ssh隧道到远程MySQL服务器

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

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

编辑:

经过一番研究,我发现了几个方法来获得一个SSH隧道

A)实现我自己的数据源(我伸出org.springframework.jdbc.datasource.DriverManagerDataSource),然后使用PostContruct和Predestroy设置/关闭SSH隧道Jsch

- >问题:SSH隧道保持打开的应用程序的生命周期,究竟是不是我想要的

B)实现我自己的驱动程序(我扩展com.mysql.jdbc.Driver),并覆盖“连接”连接前创建一个SSH隧道

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

更多欢迎提出建议

回答

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 
     ... 
    } 
    } 
} 

然后,实例化一个bean实例自定义类,而不是HikariDataSource

+0

感谢提示,不知道我可以提前自己实现dataSource。由于我目前使用的是jndi datasoruce(org.springframework.jnd.JndiObjectFactoryBean),所以我仍然需要了解如何获取连接url/port(我在Tomcat的上下文中定义的) –

+1

公开主机名和端口作为bean的属性。除了'createTunnel'和'tunnelPort'外,你还可以使用'remoteHost'和'remotePort'。 – manish

+0

以及如何获取关闭连接的句柄(关闭ssh隧道?)。据我了解,这是在Connection对象本身中实现的(在我的例子中,一个类实现了java.sql.Connectio? –