Spring AOP:方法在MethodConstraintViolationException的情况下不执行

时间:2013-12-29 23:50:49

标签: java spring bean-validation spring-aop

我有一个用JSR 303注释保护的bean。我还添加了Spring方面(@Around)来处理MethodConstraintViolationException。我的问题是:如果我使用正确的参数执行方法 - 我的方面工作(执行 - 添加了断点),但是当我运行具有不正确参数的方法时,抛出MethodConstraintViolationException并且不执行我的方面。

package noname.exception;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.validator.method.MethodConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;

import noname.service.exceptions.ValidationException;
import noname.utils.ValidationExceptionProcessor;

@Aspect
public class ExceptionAspect implements Ordered {

    @Autowired
    private ValidationExceptionProcessor processor;

    @Pointcut(value = "execution(* noname.conversionstrategy.api.IDocumentConverter.*(..))")
    public void aopDocumentConverterPointcut() {
    }

    @Pointcut(value = "execution(* noname.service.api.IMailMerger.*(..))")
    public void aopMailMargeServicePointcut() {
    }

    @SuppressWarnings("deprecation")
    @Around("aopDocumentConverterPointcut() || aopMailMargeServicePointcut()")
    public Object exceptionsAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        try {
            return proceedingJoinPoint.proceed();
        } catch ( Throwable e ) {
            if (e instanceof MethodConstraintViolationException) {
                ValidationException exp = processor.process((MethodConstraintViolationException) e);
                throw exp;
            } else {
                throw e;
            }
        }
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

Intefaces(IMailMerger和IDocumentConverter)类似:

package noname.conversionstrategy.api;

import java.util.List;

import javax.validation.constraints.NotNull;

import org.springframework.validation.annotation.Validated;

import noname.service.domain.DocumentActionInput;
import noname.service.domain.DocumentActionResult;
import noname.validator.ValidActionInput;


@Validated
public interface IDocumentConverter {

    DocumentActionResult convertDocument(@NotNull(message = "DocumentActionInput must be provided") @ValidActionInput DocumentActionInput document);

    List<DocumentActionResult> convertDocuments(@NotNull(message = "DocumentActionInput must be provided") @ValidActionInput List<DocumentActionInput> documents);

}

我认为spring执行第一次bean验证(它可能也用方面执行(?))。如果此验证抛出MethodConstraintViolationException,那么我的方面不会被执行,因为spring aop不支持从另一个方面捕获异常(需要确认)。

我还用代理创建了测试(我的方面看起来很好):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContextTest.xml"})
public class ExceptionAspectSpringTest {

    @Autowired
    private IDocumentConverter documentConverter;

    @Autowired
    private ExceptionAspect exceptionAspect;

    private IDocumentConverter proxy;

    @Before
    public void setUp() {
        AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(documentConverter);
        aspectJProxyFactory.addInterface(IDocumentConverter.class);
        aspectJProxyFactory.addAspect(exceptionAspect);
        proxy = aspectJProxyFactory.getProxy();
    }

    @Test( expected = ValidationException.class )
    public void shouldThownValidationException() {
        DocumentActionInput document = new DocumentActionInput();

        proxy.convertDocument(document);
    }
}

任何帮助表示赞赏

0 个答案:

没有答案