2015-11-05 110 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? –