2016-07-22 110 views
0

我對如何與上述方案去春混亂(依賴注入上下文)春天依賴注入方案

class Login { 
    String username; 
    String password; 
    UserAuthService userAuth; 

    /* 
     assume getter and setter 
     methods for above private 
     properties here 
    */ 

} 

UserAuthService是有一個布爾方法驗證一個接口(字符串username,字符串密碼);

它由BasicAuthService,LDAPAuthService,MockBasicAuthService,MockLDAPAuthService實現; 另外假設BasicAuthServie具有屬性serverAddress,作爲具有認證服務器IP地址的字符串, 與LDAPAuthService相同。

語境下我的問題是依賴注入和Spring,

我瞭解,基於beanconfig文件春天(的IOC)將注入的具體實施 UserAuthService之一。

1。在beanconfig文件中,我們只能配置一個ref say() 場景:假設在UI用戶有一個下拉菜單來選擇BasicAuth/LDAPAuth。用戶選擇了LDAPAuth,如何在春季處理這種情況? ,因爲我們在beanconfig文件中有硬連線ref =「beanIdBasicAuthService」)。有沒有辦法動態地改變參考?

2。稍微複雜一些(假設IT管理員等等),UI現在提供選項來選擇認證服務器的地址(這是基本/ LDAP認證服務類中的一個屬性) 再次在beanconfig文件中,我們已經硬連接了這些屬性。如何在春季改變它的動態? (除了明確獲取注入bean和調用setterMethod)

這些場景對我來說有點混亂。有人可以解釋這個嗎?

回答

0

回答這兩個問題:改爲注入工廠類。 例如在你的例子中:

class Login { 
    String username; 
    String password; 
    UserAuthServiceFactory userAuthFactory; 

    /* 
     assume getter and setter 
     methods for above private 
     properties here 
    */ 
} 

class UserAuthServiceFactory { 
    UserAuthService createUserAuth(String type, String remoteHost, ...) {...} 
} 
0

Spring提供了一些白魔法,但你真的需要黑魔法:-)。

更嚴重的是,你是正確的一方:Spring只能在bean創建時間上配置一個bean,並且只能創建bean。順便說一句,這裏還有一個範圍的問題:一個Singleton bean只會被創建一次,並且在整個應用程序中將使用同一個對象,而對於bean作用域,當從應用程序上下文請求時會構造一個新對象。

但是,一旦你有一個bean,你可以自由使用它並改變Spring初始化的值。

這就是第二個問題的方法:在UI中注入AuthService(s),並簡單地通過UI更改服務器地址(有點同步...):新地址將是從那時起使用。

對於第一個問題,我首先會說在像Login類這樣的類中注入身份驗證服務是不常見的。首先它迫使你通過對應用程序上下文的請求來創建任何Login對象,這會不必要地將你的應用程序綁定到Spring類。恕我直言,更好的設計將有一個主身份驗證類注入一個具體的身份驗證對象的容器,並委託實際身份驗證。這是Spring Security用AuthenticationManager將AuthenticationProviders的實際身份驗證委託給的。