[SPRING] 봄 AOP + Aspectj를 통한 예외 처리
SPRING봄 AOP + Aspectj를 통한 예외 처리
내 프로젝트에는 기본적으로 POJO 인 도메인 계층과 도메인 계층의 맨 위에있는 Spring 컨트롤러 / 서비스 계층이 있습니다. 나는 또한 서비스와 도메인 사이에 앉아있는 AOP 레이어를 가지고있다.
내 도메인 계층이 이제 서비스 계층에서 처리되고있는 비즈니스 예외를 던지고 있습니다.
그러나 도메인 계층에서 throw 된 예외가 AOP 계층에서 처리 될 수 있도록이를 변경하려고합니다. AOP 레이어는 어떤 종류의 오류 응답을 보내고 스프링 컨트롤러 / 웹 서비스 레이어로 다시 보냅니다.
IBizResponse를 만들고 두 개의 하위 클래스 / 인터페이스를 만들고 SuccessResponse와 ErrorResponse를 만들고 내 도메인 계층 메서드가 IBizResponse를 반환하도록 할 수 있습니다. 그러나 AOP를 ErrorResponse 객체를 서비스 계층에 반환하는 방법을 이해할 수는 없습니다.
해결법
-
==============================
1.나는 예외 처리의 경우 오류 응답 DTO를 리턴해야만했던 동일한 시나리오를 발견했다. @Aspect 클래스 내부,
나는 예외 처리의 경우 오류 응답 DTO를 리턴해야만했던 동일한 시나리오를 발견했다. @Aspect 클래스 내부,
@Aspect @Component public class MyAspect{ private static final Logger LOGGER = LoggerFactory.getLogger(MyAspect.class); @Pointcut("execution(* com.linda.dao.strategy.*.*(..))") public void strategyMethods() { } @Pointcut("execution(* com.linda.controller.*.*(..)) || execution(* com.linda.Manager.*(..))") public void controllerMethods(){ } @Around("strategyMethods()") public Object profileStrategyMethods(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object output = null; LOGGER.info("Class:"+pjp.getTarget().getClass()+" entry -> method ->"+pjp.getSignature().getName()); try{ output = pjp.proceed(); long elapsedTime = System.currentTimeMillis() - start; LOGGER.info("Method execution time: " + elapsedTime + " milliseconds."); LOGGER.info("Class:"+pjp.getTarget().getClass()+" exit -> method ->"+pjp.getSignature().getName()); }catch(Throwable t){ throw new InternalServerException(t.getMessage()); } return output; } @AfterThrowing(pointcut="execution(* com.linda.dao.strategy.*.*(..)) || execution(* com.linda.controller.*.*(..)) || execution(* com.linda.Manager.*(..))",throwing = "ex") public void doRecoveryActions(JoinPoint joinPoint, Throwable ex) { Signature signature = joinPoint.getSignature(); String methodName = signature.getName(); String stuff = signature.toString(); String arguments = Arrays.toString(joinPoint.getArgs()); LOGGER.error("Write something in the log... We have caught exception in method: " + methodName + " with arguments " + arguments + "\nand the full toString: " + stuff + "\nthe exception is: " + ex.getMessage()); } }
아래처럼 예외 처리를위한 다른 클래스를 정의했습니다 :
@ControllerAdvice public class ExceptionLogAdvice { @ExceptionHandler(InternalServerException.class) @ResponseStatus(HttpStatus.BAD_GATEWAY) @ResponseBody public ResponseEntity<Object> handleValidationException(final InternalServerException internalServerException){ ErrorResponseDTO dto = constructErrorResponse(internalServerException); return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(dto); } }
실제 코드를 공유 할 수 없기 때문에 코드를 조금 트윗했습니다. 희망을 나는 개념을 분명히했다.
-
==============================
2.https://docs.spring.io/spring/docs/4.1.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn의 조언을 던진 후를 참조하십시오.
https://docs.spring.io/spring/docs/4.1.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn의 조언을 던진 후를 참조하십시오.
예외를 throw하여 일치하는 메소드 실행이 종료 될 때 조언을 실행 한 후 실행됩니다. @AfterThrowing 주석을 사용하여 선언됩니다.
예제들
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class AfterThrowingExample { @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doRecoveryActions() { // ... } } import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class AfterThrowingExample { @AfterThrowing( pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", throwing="ex") public void doRecoveryActions(DataAccessException ex) { // ... } }
-
==============================
3.고려 com.sc.bs.impl. * 비즈니스 / 도메인 계층 패키지이며 @Around 주석을 사용하여 AOP 레이어에서 도청. 코드 스 니펫 :
고려 com.sc.bs.impl. * 비즈니스 / 도메인 계층 패키지이며 @Around 주석을 사용하여 AOP 레이어에서 도청. 코드 스 니펫 :
@Around("execution(* com.sc.bs.impl..*.*(..))") public Object exceptionHandlerWithReturnType(ProceedingJoinPoint joinPoint) throws Throwable{ try { obj = joinPoint.proceed(); } catch(Exception ex) { throw ex; } }
from https://stackoverflow.com/questions/24797157/exception-handling-through-spring-aop-aspectj by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Java Spring 특정 Bean 재 작성 (0) | 2019.07.17 |
---|---|
[SPRING] 스프링 부트 로그를 어떻게 탄력성에 직접 섭취합니까? (0) | 2019.07.16 |
[SPRING] 봄 부팅, 최대 절전 모드 검색 속성 (0) | 2019.07.16 |
[SPRING] jUnit 테스트에서 Spring @Service 객체에 액세스하는 방법 (0) | 2019.07.16 |
[SPRING] 하나의 트랜잭션에서 Hibernate와 JDBC (0) | 2019.07.16 |