@@ -75,6 +75,8 @@ public enum ErrorCode {
7575
7676** ` ErrorReponse.java ` (返回给客户端具体的异常对象)**
7777
78+ 这个类作为异常信息返回给客户端,里面包括了当出现异常时我们想要返回给客户端的所有信息。
79+
7880``` java
7981import org.springframework.util.ObjectUtils ;
8082
@@ -127,6 +129,8 @@ public class ErrorReponse {
127129
128130** ` BaseException.java ` (继承自 ` RuntimeException ` 的抽象类,可以看做系统中其他异常类的父类)**
129131
132+ 系统中的异常类都要继承自这个类。
133+
130134``` java
131135
132136public abstract class BaseException extends RuntimeException {
@@ -177,7 +181,9 @@ public class ResourceNotFoundException extends BaseException {
177181
178182** ` GlobalExceptionHandler.java ` (全局异常捕获)**
179183
180- ` @ExceptionHandler ` 捕获异常的过程中,会优先找到最匹配的。
184+ 我们定义了两个异常捕获方法。
185+
186+ 这里再说明一下,实际上这个类只需要 ` handleAppException() ` 这一个方法就够了,因为它是本系统所有异常的父类。只要是抛出了继承 ` BaseException ` 类的异常后都会在这里被处理。
181187
182188``` java
183189import com.twuc.webApp.web.ExceptionController ;
@@ -192,7 +198,9 @@ import javax.servlet.http.HttpServletRequest;
192198@ControllerAdvice (assignableTypes = {ExceptionController . class})
193199@ResponseBody
194200public class GlobalExceptionHandler {
195-
201+
202+ // 也可以将 BaseException 换为 RuntimeException
203+ // 因为 RuntimeException 是 BaseException 的父类
196204 @ExceptionHandler (BaseException . class)
197205 public ResponseEntity<?> handleAppException (BaseException ex , HttpServletRequest request ) {
198206 ErrorReponse representation = new ErrorReponse (ex, request. getRequestURI());
@@ -208,6 +216,43 @@ public class GlobalExceptionHandler {
208216
209217```
210218
219+ ** (重要)一点扩展:**
220+
221+ 哈哈!实际上我多加了一个算是多余的异常捕获方法` handleResourceNotFoundException() ` 主要是为了考考大家当我们抛出了 ` ResourceNotFoundException ` 异常会被下面哪一个方法捕获呢?
222+
223+ 答案:
224+
225+ 会被` handleResourceNotFoundException() ` 方法捕获。因为 ` @ExceptionHandler ` 捕获异常的过程中,会优先找到最匹配的。
226+
227+ 下面通过源码简单分析一下:
228+
229+ ` ExceptionHandlerMethodResolver.java ` 中` getMappedMethod ` 决定了具体被哪个方法处理。
230+
231+ ``` java
232+
233+ @Nullable
234+ private Method getMappedMethod(Class<? extends Throwable > exceptionType) {
235+ List<Class<? extends Throwable > > matches = new ArrayList<> ();
236+ // 找到可以处理的所有异常信息。mappedMethods 中存放了异常和处理异常的方法的对应关系
237+ for (Class<? extends Throwable > mappedException : this . mappedMethods. keySet()) {
238+ if (mappedException. isAssignableFrom(exceptionType)) {
239+ matches. add(mappedException);
240+ }
241+ }
242+ // 不为空说明有方法处理异常
243+ if (! matches. isEmpty()) {
244+ matches. sort(new ExceptionDepthComparator (exceptionType));
245+ // 返回处理异常的方法
246+ return this . mappedMethods. get(matches. get(0 ));
247+ }
248+ else {
249+ return null ;
250+ }
251+ }
252+ ```
253+
254+ 从源代码看出:** ` getMappedMethod() ` 会首先找到可以匹配处理异常的所有方法信息,然后对其进行从小到大的排序,最后取最小的那一个匹配的方法(即匹配度最高的那个)。**
255+
211256## 写一个抛出异常的类测试
212257
213258** ` Person.java ` **
0 commit comments