2010-07-28 124 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,所以你不需要做自我调用“接口”的方法;这种事常常表示应用程序功能的分区不正确。