使用Spring AOP仅使用注释的拦截方法

时间:2010-04-10 02:18:14

标签: java spring annotations spring-aop

在我的Spring上下文文件中,我有类似这样的内容:

<bean id="userCheck" class="a.b.c.UserExistsCheck"/>
<aop:config>
      <aop:aspect ref="userCheck">
         <aop:pointcut id="checkUser"
                expression="execution(* a.b.c.d.*.*(..)) &amp;&amp; args(a.b.c.d.RequestObject)"/>
         <aop:around pointcut-ref="checkUser" method="checkUser"/>
      </aop:aspect>
</aop:config>    

a.b.c.UserExistsCheck看起来像这样:

@Aspect
public class UserExistsCheck {

@Autowired
private UserInformation userInformation;

public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {
    int userId = ... //get it from the RequestObject passed as a parameter
    if (userExists(userId)) {
        return pjp.proceed();
    } else {
        return new ResponseObject("Invalid user);
    }
}

正在被这些东西拦截的类看起来像这样:

public class Klazz {
    public ResponseObject doSomething(RequestObject request) {...}
}

这很有效。在将呼叫传递给Klazz之前,会根据需要执行UserExistCheck。问题是,这是我让它运作的唯一方法。通过使用注释而不是上下文文件来实现这一点似乎对我的小脑子来说太过分了。那么......我究竟应该如何在UserExistsCheck和Klazz中注释方法?我还需要其他东西吗?另一堂课?上下文文件中还有什么内容?

3 个答案:

答案 0 :(得分:5)

您是否启用了基于注释的AOP? documentation表示您必须添加

<aop:aspectj-autoproxy/>

到您的弹簧配置。然后,您需要在checkUser方法前添加注释。看起来您需要@Around建议,如here所述。

@Aspect
public class UserExistsCheck {

  @Around("execution(* a.b.c.d.*.*(..)) && args(a.b.c.d.RequestObject)")
  public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {

答案 1 :(得分:3)

从您提供的示例代码中,您似乎正在尝试为未实现任何接口的类创建建议。如Spring文档的Proxying Mechanisms部分所述,如果您要执行此操作,则需要启用CGLIB:

<aop:aspectj-autoproxy proxy-target-class="true" />

我个人觉得这比文档所指出的要复杂得多,虽然如果所有星星都正确对齐,它确实有效,但它往往更容易 - 从设计的角度来看更可取 - - 在接口上声明您的AOP建议,如下所示。 (请注意,您需要从KlazzImpl / BeanFactory获取ApplicationContext的实例。)

public interface Klazz {
  ResponseObject doSomething(RequestObject request);
}

public class KlazzImpl implements Klazz {
  public ResponseObject doSomething(RequestObject request) {...}
}

此外,您对args表达式的使用有点偏离。请参阅以下内容:

@Aspect
public class UserExistsCheck {
  @Autowired
  private UserInformation userInformation;

  @Around("execution(* a.b.c.d.*.*(..)) && args(reqObj)")
  public Object checkUser(ProceedingJoinPoint pjp, a.b.c.d.RequestObject reqObj) throws Throwable {
      // ...
  }
}

这些改变应该可以胜任。

答案 2 :(得分:1)

从春季3.1开始,将@EnableAspectJAutoProxy(proxyTargetClass=true)添加到您的@Configuraiton