2012-04-10 25 views
1

爲了處理<intercept-url>中的自定義表達式,我爲WebExpressionVoter提供了自定義表達式處理程序。此自定義表達式處理程序以與DefaultWebSecurityExpressionHandler相同的方式實現WebSecurityExpressionHandler,並重寫其createEvaluationContext方法以返回具有我自定義根對象集的上下文。這個自定義根對象只是用另一種方法擴展WebSecurityExpressionRoot。這是DefaultWebSecurityExpressionHandler是怎麼做的:spring安全 - 如何爲WebSecurityExpressionHandler或其子類自動裝入自定義rootObject?

public EvaluationContext createEvaluationContext(Authentication authentication, FilterInvocation fi) { 
     StandardEvaluationContext ctx = new StandardEvaluationContext(); 
     SecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi); 
     root.setTrustResolver(trustResolver); 
     root.setRoleHierarchy(roleHierarchy); 
     ctx.setRootObject(root); 

     return ctx; 
    } 

它創建的WebSecurityExpressionRoot一個新對象,並將其分配,因爲它返回的評價上下文的根對象,但使用DI禁止WebSecurityExpressionRoot(因爲它的創作不被處理由春天)。我想在xml文件中配置自定義表達式根,以便我可以將其注入到WebSecurityExpressionHandler的擴展中,並使用註釋向其中注入資源。

問題是WebSecurityExpressionRoot的構造函數的參數是動態的,我不能在xml中將它指定爲一個bean時指定它們。有沒有辦法通過DI將我的自定義表達式根注入到WebSecurityExpressionHandler的子類中?

回答

3

你可以聲明WebSecurityExpressionRoot作爲prototype -scoped豆與動態指定的構造函數參數實例吧:

<bean id = "webSecurityExpressionRoot" class = "...WebSecurityExpressionRoot" 
    scope = "prototype"> 
    ... 
</bean> 

SecurityExpressionRoot root = applicationContext.getBean(
    "webSecurityExpressionRoot", authentication, fi); 

ApplicationContext可以注入你的WebSecurityExpressionHandler使用ApplicationContextAware成。

+0

謝謝。但是,我們可以通過對ExpressionRoot類型的屬性進行註釋來注入表達式根?它會更乾淨。 – Daud 2012-04-10 15:34:45

+1

@Daud:無論如何你需要提供構造函數參數。如果您不想將'WebSecurityExpressionHandler'與'ApplicationContext'耦合在一起,則向其注入一個工廠。 – axtavt 2012-04-10 15:38:01

+0

它有點偏離主題,但爲什麼我們的類與ApplicationContext耦合不被認爲是一種好的做法? – Daud 2012-04-11 05:29:54