라울 베르토네 거의 맞다 정의. 로직을 반대로하고 ExceptionConversionAspect
이 우선되어야합니다. 자바 SE에 대한
완전 작업 샘플 (난 그냥 자바 EE 예외를 에뮬레이트) :
도우미 클래스 :
package javax.validation;
public class ConstraintViolationException extends RuntimeException {
private static final long serialVersionUID = -8041265519275356912L;
public ConstraintViolationException(String arg0) {
super(arg0);
}
}
package com.myexample.validator.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {}
package com.myexample.service;
public class InvalidServiceInputException extends RuntimeException {
public InvalidServiceInputException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
}
샘플 드라이버 응용 프로그램 :
드라이버 응용 프로그램은 @Validate
으로 주석을 달고 서비스를 에뮬레이트합니다 (패키지 이름 참조). 이것은 10 개의 메소드 호출을 반복하고, 예외를 잡아 내고 표준 출력으로 출력하여 실제로 원하는대로 변환되었음을 보여줍니다.
package com.myexample.service;
import com.myexample.validator.annotation.Validate;
@Validate
public class Application {
public void doSomething(int i) {
System.out.printf("Doing something #%d%n", i);
}
public static void main(String[] args) {
Application application = new Application();
for (int i = 0; i < 10; i++) {
try {
application.doSomething(i + 1);
}
catch (Exception e) {
System.out.println(e);
System.out.println(" cause: " + e.getCause());
}
}
}
}
양태 :가
검증 양태 임의로 데모 목적으로 ConstraintViolationException
을 던진다.
package com.myexample.aspect;
import java.util.Random;
import javax.validation.ConstraintViolationException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class ValidateAspect {
private static final Random RANDOM = new Random();
@Around("execution(public !static * *(..)) && @within(com.myexample.validator.annotation.Validate)")
public Object validateMethodInvocation(ProceedingJoinPoint thisJoinPoint) throws Throwable {
Object result = thisJoinPoint.proceed();
if (RANDOM.nextBoolean())
throw new ConstraintViolationException("uh-oh");
return result;
}
}
예외 변환 형태는 이제 추가적인 @DeclarePrecedence
주석을 갖는다.
package com.myexample.aspect;
import javax.validation.ConstraintViolationException;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclarePrecedence;
import com.myexample.service.InvalidServiceInputException;
@Aspect
@DeclarePrecedence("ExceptionConversionAspect, *")
public class ExceptionConversionAspect {
@AfterThrowing(pointcut = "execution(* com.myexample.service..*(..))", throwing = "e")
public void convertServiceException(Exception e) {
if (e instanceof ConstraintViolationException) {
throw new InvalidServiceInputException("The service inputs failed validation", e);
}
}
}
콘솔 출력 :
Doing something #1
Doing something #2
com.myexample.service.InvalidServiceInputException: The service inputs failed validation
cause: javax.validation.ConstraintViolationException: uh-oh
Doing something #3
com.myexample.service.InvalidServiceInputException: The service inputs failed validation
cause: javax.validation.ConstraintViolationException: uh-oh
Doing something #4
Doing something #5
Doing something #6
com.myexample.service.InvalidServiceInputException: The service inputs failed validation
cause: javax.validation.ConstraintViolationException: uh-oh
Doing something #7
Doing something #8
Doing something #9
Doing something #10
는 어쩌면 그것은 validateMethodInvocation 방법에 대한 측면을 만드는 데 도움이 될 것이다 -이 예외에 의해 트리거하는 방법으로 던져 질 것 또는 적절한 예외를 던지고 있도록 ValidateAspect를 대체? –