Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement the spring global exception interceptor

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article is about how to implement the spring global exception interceptor. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

You may ask, Spring already has its own global exception intercept, so why repeat the wheel?

This is a good question. I think there are several reasons.

Pretend to be forced

The global exception interception of Spring is only for the interface of Spring MVC, but there is nothing you can do about your RPC interface.

Cannot be customized

Besides writing business code, we can actually do something else.

I think the above reasons have fully answered why we have to repeat the construction of wheels. Next, let's take a look at how to build wheels.

What kind of wheels do you build?

I think global exception interception should have the following characteristics

Easy to use, preferably consistent with the original use of spring, reduce the cost of learning

Able to support all interfaces

Calling exception handlers can be expected, such as processors that define RuntimeException and Exception. If NullPointException is thrown at this time, the expected processor should be selected without ambiguity.

How to build wheels?

Since the current applications are basically based on spring, I also implement global exception interception based on SpringAop.

First, define a few comments.

Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented@Componentpublic @ interface ExceptionAdvice {} @ Target (ElementType.METHOD) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface ExceptionHandler {Class clazz = bean.getClass (); ExceptionAdvice advice = clazz.getAnnotation (ExceptionAdvice.class); if (advice = = null) return bean;if (exceptionMethodPool! = null) throw new RuntimeException ("two exception definition classes are not allowed"); exceptionMethodPool = new ExceptionMethodPool (bean) / / keep the order of exception handling methods Arrays.stream (clazz.getDeclaredMethods ()) .filter (method-> method.getAnnotation (ExceptionHandler.class)! = null) .forEach (method-> {ExceptionHandler exceptionHandler = method.getAnnotation (ExceptionHandler.class); Arrays.stream (exceptionHandler.value ()) .forEach (c-> exceptionMethodPool.add (cForce method);}); / / register to spring container context.getBeanFactory (). RegisterSingleton ("exceptionMethodPool", exceptionMethodPool); return bean;}}

By implementing the BeanPostProcessor interface, ExceptionBeanPostProcessor plugs all exception handlers into the ExceptionMethodPool and registers them into the Spring container before bean initialization

Then define the exception handler

@ Componentpublic class ExceptionProcessor {@ Autowiredprivate ExceptionMethodPool exceptionMethodPool; public BaseResponse process (Throwable e) {return (BaseResponse) FunctionUtil.computeOrGetDefault (()-> {Method method = exceptionMethodPool.obtainMethod (e); method.setAccessible (true); return method.invoke (exceptionMethodPool.getExcutor (), e);}, new BaseResponse (0, "unknown error");}}

Some syntax candy encapsulated by myself through functional programming is applied here. If you are interested, you can take a look.

Finally, intercept through AOP

@ Aspect@Componentpublic class ExceptionInterceptAop {@ Autowiredprivate ExceptionProcessor exceptionProcessor; @ Pointcut ("@ annotation (com.example.exception.intercept.ExceptionIntercept)") public void pointcut () {} @ Around ("pointcut ()") public Object around (ProceedingJoinPoint point) {return computeAndDealException (()-> point.proceed (), e-> exceptionProcessor.process (e));} public static R computeAndDealException (ThrowExceptionSupplier supplier, Function dealFunc) {try {return supplier.get ();} catch (Throwable e) {return dealFunc.apply (e) } @ FunctionalInterfacepublic interface ThrowExceptionSupplier {T get () throws Throwable;}}

At this point, the code part is complete, let's take a look at how to use

@ ExceptionAdvicepublic class ExceptionConfig {@ ExceptionHandler (value = NullPointerException.class) public BaseResponse process (NullPointerException e) {return new BaseResponse (0, "NPE");} @ ExceptionHandler (value = Exception.class) public BaseResponse process (Exception e) {return new BaseResponse (0, "Ex");} @ RestControllerpublic class TestControler {@ RequestMapping ("/ test") @ ExceptionInterceptpublic BaseResponse test (@ RequestParam ("a") Integer a) {if (a = = 1) {return new BaseResponse (1m a + ");} else if (a = = 2) {throw new NullPointerException () } else throw new RuntimeException ();}}

We define the class of the exception handler through the @ ExceptionAdvice flag, and then use the @ ExceptionHandler annotation to handle the exception, making it easy to collect

Finally, we use @ ExceptionIntercept to intercept the methods that require exception interception.

I didn't use Spring to find a matching exception handler in the way it matches the nearest parent class. I think this design is a failure for the following reasons

Complex code

You can't see which exception handler to call at a glance, especially when there are a lot of defined exception handlers, and it's even harder to find multiple defined classes. You may have to read all the processors before you know which one to call.

For the above considerations, I only keep one exception handler definition class, and the matching order is the same as the method definition order, matching from top to bottom, so as long as I find a handler that can handle it, then I know how to call the

Thank you for reading! This is the end of the article on "how to implement the global exception blocker for spring". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report