2017-05-15 61 views
0

我有一個Spring bean,它指向連接工廠訪問J2C資源。此代碼部署在2個jvms負載平衡的WebSphere服務器中。我將readAuth方法作爲bean xml中的init方法,但在加載測試期間多次調用它。由於Spring單例是每個容器每個bean,我假設有多個容器導致它加載多次。所以我刪除了init方法,並將用戶名和密碼更改爲static,並在get方法中添加了null檢查。但是現在,readAuth方法也被多次調用。我想確保每個jvm僅調用一次此方法,因爲此方法在負載測試期間訪問服務器資源和連接超時。 請提出一個關於如何寫這堂課的最佳方法。提前致謝。Spring bean如何只訪問一次服務器資源?

<bean id="J2CUtils" 
     class="test.J2CUtils"> 
     <property name="connectionFactory" ref="connectionFactory" /> 
    </bean> 
    <jee:jndi-lookup id="connectionFactory" jndi-name="eis/J2CAuth" /> 

public class J2Ctils { 
    private ConnectionFactory connectionFactory; 
    private static String userName; 
    private static String password; 

    private void readAuth() throws ResourceException { 
     System.out.println("Auth loaded"); 
      Connection conn = connectionFactory.getConnection(); 
      Interaction interaction = (Interaction) conn.createInteraction(); 
      Config config = interaction.getConfig(); 
      userName = config.getUserName(); 
      password = config.getPassword(); 
    } 
    public String getUserName() { 
     if(null == userName) { 
      readAuth(); 
     } 
     return userName; 
    } 
    public String getPassword() { 
     if(null == password) { 
      readAuth(); 
     } 
     return password; 
    } 
    public void setConnectionFactory(ConnectionFactory connectionFactory) { 
     this.connectionFactory = connectionFactory; 
    } 
} 

回答

0

單身或靜態方法,如果你要訪問的資源正好一次,因爲集羣中的每個成員都有自己的類的實例沒有幫助。

請記住,Java EE規範Spring specification都沒有定義任何類型的集羣行爲。您需要搜索特定的供應商解決方案來實現這種要求。正如一個例子,看看@ApplicationScped in a cluster

存檔預期行爲的其他方法是使用像Zookeeper這樣的分佈式鎖,或者甚至可以使用帶有duplicate message filter的隊列。

+0

集羣中有2個jvms。如果羣集中每個jvm有一個實例,那麼我沒關係。但負載測試2分鐘和5分鐘顯示該方法被稱爲7次和12次。而對於30,000個請求,我用4個jvms獲得了大約100個連接超時。所以我的意圖是避免這些連接超時。有沒有一種方法可以確保每個jvm使用靜態類/方法/變量只有一次實例? – Gokul

+0

默認的Spring Beans是單例,即它們每個JVM只存在一次。如果將'getUserName()'和'getPassword()'標記爲'synchronized',那麼除了用戶名或密碼爲'null'或重新加載spring上下文外,readAuth()'只會在每個bean上調用一次。 – andih

相關問題