2010-07-28 440 views
0

我有這樣的對象:春季安全和@PostFilter

@Service 
public class myBr { 

    @PostFilter("filterObject.cellule.getId()==2") 
    public List<Bibliotheque> getB() { 
     return super.getAll(); 
    } 

    public List<Bibliotheque> getA() { 
     return getB(); 
    } 
} 

當我從一個試驗,做myBr.getB()打電話時,@PostFilter應用,但是當我打電話myBr.getA(),後濾波器不工作。

有沒有辦法處理這個問題,以便過濾器被應用?

回答

1

我假設你已經解決了你的問題,但是如果有人想知道與他的bean調用類似的東西(我有與EJB相同的問題): 方法註釋被容器/應用程序上下文讀取或無論是處理注射。而且,在這種情況下,需要某種攔截器來觸發預期的行爲,它僅適用於來自bean「外部」的調用,即圍繞您的bean的代理對象。 getA()在這種情況下是一個本地調用,所以在技術上你的線程直接跳轉到方法getB(),但它根本不考慮任何註釋。

0

我認爲我能想到的唯一可能的解決方案是在getA方法中添加一個@PostFilter註釋。 這是因爲註釋的工作原理是在類實例的周圍創建一個代理對象,用於添加和處理表達式的通知(在這種情況下在方法被調用後)這是一個面向方面的技巧,但是當您從同樣的情況下,創建的建議永遠不會被調用,這就是爲什麼它不以這種方式工作。

9

問題是@PostFilter通過AOP技術應用,但您直接從getA()調用實例的getB()實現,並且Spring AOP不重寫類。

這裏是發生了什麼事情:

 +————————+  +——————————+ 
getA | pass | getA |   | 
—————>|·······>|—————>|   |———+ 
     |  |  |   | | 
     | Bean |  | Instance | | this.getB 
     |  |  |   | | 
getB | filter | getB |   | | 
—————>|·······>|—————>|   |<——+ 
     |  |  |   | 
     +————————+  +——————————+ 

Spring AOP中提出的代理對象爲實際的bean委託給你的bean,或者通過使用JDK代理對象(如果你已經有了一個合適的接口)或通過使用CGLIB合成對象de novo。對於getA它只是直接通過,並且對於getB它將呼叫插入後過濾代碼。這很好,但它確實意味着當實例 - this內部的this - 用於直接調用getB時,它會跳過篩選器並跳轉到底層代碼。

有四種可能的修復方法。

  1. 使用AspectJ來執行代碼重寫的AOP代碼的應用(代價是更復雜的部署)。
  2. 爲實例指定bean的句柄(必須明確地完成;不能自動裝載它)並通過它調用getB
  3. getB置於不同的bean中。
  4. 對兩種方法進行過濾。

我自己使用了選項#2(它比我的特殊情況下的選擇更容易),它工作得很好,但最好的選擇幾乎可以肯定是#3,所以你不需要做自我調用「接口」的方法;這種事常常表示應用程序功能的分區不正確。