Spring Annotation AOP 기반 예외 처리 방법의 Java 예제 코드
이 글은 주로 Spring Annotation AOP를 기반으로 한 Java 예외 처리 방법을 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.
1. 소개
처음 프로젝트를 개발할 때는 준비가 완벽하지 않았습니다. 개발이 특정 수준에 도달한 후에야 아직 해결되지 않은 문제가 있다는 것을 깨닫게 될 것입니다. 예를 들어, 오늘 저는 예외 처리라는 문제에 대해 이야기하고 싶습니다. 프로그램을 작성할 때 예외는 일반적으로 try...catch...finally를 통해 처리되는데, 프로그램을 작성할 때 실제로 가능한 모든 예외를 처리할 수 있을까요? 그리고 예외가 발생했을 때 어떤 로직이 실행되는지, 어떤 프롬프트 정보가 반환되는지, 어떤 페이지로 이동할지 등을 모두 고려해야 합니다.
2. @ControllerAdvice(향상된 컨트롤러) 기반 예외 처리
@ControllerAdvice 주석은 내부적으로 @ExceptionHandler, @InitBinder 및 @ModelAttribute 주석이 달린 메서드는 모든 @RequestMapping 주석이 달린 메서드에 적용됩니다. 이 예제에서는 ExceptionHandler를 사용하여 발생하는 예외를 처리하기 위해 @RequestMapping 주석이 달린 모든 메서드에 적용합니다.
샘플 코드:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import com.hjz.exception.ServiceException; import com.hjz.exception.utils.ExceptionUtils; @ResponseBody public class ExceptionAdvice { private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionAdvice.class); /** * 拦截web层异常,记录异常日志,并返回友好信息到前端 * 目前只拦截Exception,是否要拦截Error需再做考虑 * * @param e 异常对象 * @return 异常提示 */ @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception e) { //不需要再记录ServiceException,因为在service异常切面中已经记录过 if (!(e instanceof ServiceException)) { LOGGER.error(ExceptionUtils.getExcTrace(e)); } HttpHeaders headers = new HttpHeaders(); headers.set("Content-type", "text/plain;charset=UTF-8"); headers.add("icop-content-type", "exception"); String message = StringUtils.isEmpty(e.getMessage()) ? "系统异常!!" : e.getMessage(); return new ResponseEntity<>(message, headers, HttpStatus.OK); } }
작동하지 않는 경우 spring-mvc 구성 파일에 ControllerAdvice 구성
<context:component-scan base-package="com.sishuok.es" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>
3. AOP 기반 예외 처리
1. 컨트롤러 계층 예외 처리 WebExceptionAspect .java
import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.hjz.exception.ServiceException; import com.hjz.exception.utils.ExceptionUtils; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * web异常切面 * 默认spring aop不会拦截controller层,使用该类需要在spring公共配置文件中注入改bean, * 另外需要配置<aop:aspectj-autoproxy proxy-target-class="true"/> */ @Aspect public class WebExceptionAspect { private static final Logger LOGGER = LoggerFactory.getLogger(WebExceptionAspect.class); @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)") private void webPointcut() {} /** * 拦截web层异常,记录异常日志,并返回友好信息到前端 * 目前只拦截Exception,是否要拦截Error需再做考虑 * * @param e 异常对象 */ @AfterThrowing(pointcut = "webPointcut()", throwing = "e") public void handleThrowing(Exception e) { //不需要再记录ServiceException,因为在service异常切面中已经记录过 if (!(e instanceof ServiceException)) { LOGGER.error(ExceptionUtils.getExcTrace(e)); } String errorMsg = StringUtils.isEmpty(e.getMessage()) ? "系统异常" : e.getMessage(); writeContent(errorMsg); } /** * 将内容输出到浏览器 * * @param content 输出内容 */ private void writeContent(String content) { HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); response.reset(); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Type", "text/plain;charset=UTF-8"); response.setHeader("icop-content-type", "exception"); PrintWriter writer = null; try { writer = response.getWriter(); } catch (IOException e) { e.printStackTrace(); } writer.print(content); writer.flush(); writer.close(); } }
2. 서비스 계층 예외 처리 ServiceExceptionAspect .java
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import com.hjz.exception.ServiceException; import com.hjz.exception.utils.ExceptionUtils; @Aspect public class ServiceExceptionAspect { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceExceptionAspect.class); /** * @within(org.springframework.stereotype.Service),拦截带有 @Service 注解的类的所有方法 * @annotation(org.springframework.web.bind.annotation.RequestMapping),拦截带有@RquestMapping的注解方法 */ @Pointcut("@within(org.springframework.stereotype.Service) && execution(public * *(..))") private void servicePointcut() {} /** * 拦截service层异常,记录异常日志,并设置对应的异常信息 * 目前只拦截Exception,是否要拦截Error需再做考虑 * * @param e 异常对象 */ @AfterThrowing(pointcut = "servicePointcut()", throwing = "e") public void handle(JoinPoint point, Exception e) { LOGGER.error(ExceptionUtils.getExcTrace(e)); String signature = point.getSignature().toString(); String errorMsg = getMessage(signature) == null ? (StringUtils.isEmpty(e.getMessage()) ? "服务异常" : e.getMessage()) : getMessage(signature); throw new ServiceException(errorMsg, e); } /** * 获取方法签名对应的提示消息 * * @param signature 方法签名 * @return 提示消息 */ private String getMessage(String signature) { return null; } }
3. 사용하려면 spring의 공개 구성 파일에 다음 구성을 추가하세요:
<aop:aspectj-autoproxy proxy-target-class="true" /> <bean class="com.hjz.exception.aspect.ServiceExceptionAspect" /> <bean class="com.hjz.exception.aspect.WebExceptionAspect" />
또는 등록 클래스 ServiceExceptionAspect.java 및 WebExceptionAspect 모두 사용자 정의 .java @Component 주석 추가
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; /** * 异常相关bean注册类 */ @Configuration @EnableAspectJAutoProxy @ComponentScan("com.hjz.exception.aspect") public class ExceptionConfig { }
@Aspect @Component public class WebExceptionAspect { .......... } @Aspect @Component public class ServiceExceptionAspect { ......... }
4. 의심
@within(org.springframework.stereotype.Service), @Service
@annotation(org.springframework.web.bind.annotation. RequestMapping ), @RquestMapping
으로 주석이 달린 메서드를 가로챕니다. 5. 테스트
컨트롤러 계층과 서비스 계층에 대한 예외 테스트 클래스를 각각 작성합니다. 이것은 매우 간단합니다. 메서드에서 예외를 발생시키기만 하면 됩니다. 마지막으로 예외 발생 시 @AfterThrowing에 해당하는 메소드가 실행되는지 확인하면 된다. 자세한 내용은 제가 작성한 데모를 봐주세요, 헤헤헤! ! !
위 내용은 Spring Annotation AOP를 기반으로 한 Java의 예외 처리 방법 예제 코드 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

Java는 초보자와 숙련된 개발자 모두가 배울 수 있는 인기 있는 프로그래밍 언어입니다. 이 튜토리얼은 기본 개념부터 시작하여 고급 주제를 통해 진행됩니다. Java Development Kit를 설치한 후 간단한 "Hello, World!" 프로그램을 작성하여 프로그래밍을 연습할 수 있습니다. 코드를 이해한 후 명령 프롬프트를 사용하여 프로그램을 컴파일하고 실행하면 "Hello, World!"가 콘솔에 출력됩니다. Java를 배우면 프로그래밍 여정이 시작되고, 숙달이 깊어짐에 따라 더 복잡한 애플리케이션을 만들 수 있습니다.
