Spring AOP AsjectJ注释:为多个方法定义切入点

时间:2014-02-03 01:59:51

标签: java spring aop aspectj spring-aop

我通过建议定义了两种方法的执行:

SampleBusinessLogicImpl.updateSample(示例示例) SampleBusinessLogicImpl.createSample(示例示例)

但我的建议仅针对第一个update()方法执行。 我在这里做错了什么?

@Aspect
public class SampleDynamicValidationAspect {

    private static final Logger logger = LoggerFactory.getLogger(SampleDynamicValidationAspect.class); 

    /**
    private SampleTblDAO dao; //DAOs can be used inside dynamic validations
    **/


    @Before("execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.updateSample(com.rakuten.gep.sample.entity.common.Sample,..)) && args(sample,..) throws *Exception"
            +"|| execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.createSample(com.rakuten.gep.sample.entity.common.Sample,..)) && args(sample,..) throws *Exception")
    public void validate(Sample sample) throws SampleException {
        //Dynamic validation here.
        //If some validation is failed, wrapped the appropiate exception in SampleException
        System.out.println("Involking Dynamic Validator");
    }
}

我的SampleBusinessLogicImpl类如下:

@Service
public class SampleBusinessLogicImpl implements SampleBusinessLogic {

    @Autowired
    @Qualifier(value="proxySampleTblDao")
    private SampleTblDao sampleTblDao;

    @Override
    @Transactional(rollbackFor=Exception.class)
    public Sample createSample(Sample sample) throws SampleException {
        //..
    }


    @Override
    @Transactional(rollbackFor=Exception.class)
    public Sample updateSample(Sample sample) throws SampleException {
      //..

    }
}

2 个答案:

答案 0 :(得分:2)

Pointcut中定义匹配方法表达式时,它应该与您希望advice

的实际方法相匹配

这是你的切入点表达式

@Before("execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.updateSample(com.rakuten.gep.sample.entity.common.Sample,..) throws *Exception) && args(sample,..)"
            +"|| execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.createSample(com.rakuten.gep.sample.entity.common.Sample,..) throws *Exception) && args(sample,..)")
  

<强>原因:

在您的情况下,方法签名是

public Sample createSample(Sample sample) throws SampleException {
public Sample updateSample(Sample sample) throws SampleException {

但是,你的切入点是

@Before("execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.updateSample(com.rakuten.gep.sample.entity.common.Sample,..)) && args(sample,..) throws *Exception"
            +"|| execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.createSample(com.rakuten.gep.sample.entity.common.Sample,..)) && args(sample,..) throws *Exception")

请注意,throws *Exception位于pointcut表达式中的方法声明之外。这就是切入点表达式与方法声明不匹配的原因。 将throws *Exception移到execution(内即可。我刚尝试过。

澄清只调用一种方法。

是的,实际上......您无需指定throws *Exception。仅仅使用方法就足够了所以,如果你完全删除它,它将完全正常,两种方法执行。现在,为什么更新工作是因为,它在Pointcut表达式中首先声明。因此,Pointcut匹配updateSample()的方法声明然后遇到不合适的*Exception和||适用于*Exception,实际上什么都不是。

现在,如果你只是按照声明的方式翻转切入点表达式,那就是错误的表达式。只有createSample才有效,因为这是切入点表达式中匹配的唯一一个。 请注意,)也会在execution expression中关闭。

@Before("execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.createSample(com.rakuten.gep.sample.entity.common.Sample,..) throws *Exception) && args(sample,..)"
            +"|| execution(public * com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.updateSample(com.rakuten.gep.sample.entity.common.Sample,..) throws *Exception) && args(sample,..)") 

另外,来自Spring AOP文档

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

除了返回类型模式之外的所有部分(上面代码片段中的ret-type-pattern),名称模式, 和参数模式是可选的。

希望,我能够帮助解决疑问。

答案 1 :(得分:0)

您可以像这样定义

@Before(value="( execution(* com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.updateSample(..))"
    + "|| execution(* com.rakuten.gep.sample.businesslogic.impl.SampleBusinessLogicImpl.createSample(..)))"
    + " && args(sample)")