In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the execution order of Spring AOP". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Problem description
The company's new project needs to build a new front and back separation HTTP service. I chose SpringBoot Web, which I am familiar with at present, to quickly build a usable system.
Lu Xun said, do not upgrade the version that is already in stable use. I do not believe this evil, relying on their own use of Spring for so long, how can not rush it. Needless to say, I directly introduced the latest version of SprinBoot 2.3.4.RELEASE and began to build a framework for the project.
At first, most of the components were introduced smoothly. I thought it was almost done, but I stumbled when I built the log section.
As an interface service, in order to query the call of the interface and locate the problem, the request log is usually printed out, and the AOP of Spring perfectly meets the needs of log recording as aspect support.
In the previous project, the effect of running the correct section logging is as follows:
You can see a method call in the figure, which outputs request url, entry and exit parameters, request IP, and so on. In order to look good, a split line was added before.
I put this implementation class in a new project and implemented it like this:
I rubbed my eyes and took a closer look at the copied old code. The simplified version is as follows:
/ * weave * @ param joinPoint * @ throws Throwable * / @ Before ("webLog ()") public void doBefore (JoinPoint joinPoint) throws Throwable {/ / start printing request log ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes (); HttpServletRequest request = attributes.getRequest (); / / initialize traceId initTraceId (request) before the pointcut; / / print request related parameters LOGGER.info ("= Start = =") / / print request url LOGGER.info ("URL: {}", request.getRequestURL (). ToString ()); / / print Http method LOGGER.info ("HTTP Method: {}", request.getMethod ()) / / print the full path of calling controller and the execution method LOGGER.info ("Class Method: {}. {}", joinPoint.getSignature (). GetDeclaringTypeName (), joinPoint.getSignature (). GetName ()); / / print the requested IP LOGGER.info ("IP: {}", IPAddressUtil.getIpAdrress (request)) / / print request input parameter LOGGER.info ("Request Args: {}", joinPoint.getArgs ());} / * * weave * @ throws Throwable * / @ After ("webLog ()") public void doAfter () throws Throwable {LOGGER.info ("= = End = =") after the pointcut } / * surround * @ param proceedingJoinPoint * @ return * @ throws Throwable * / @ Around ("webLog ()") public Object doAround (ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long startTime = System.currentTimeMillis (); Object result = proceedingJoinPoint.proceed (); / / print out the parameter LOGGER.info ("Response Args: {}", result) / / time-consuming LOGGER.info ("Time-Consuming: {} ms", System.currentTimeMillis ()-startTime); return result;}
The code feels like there's nothing wrong with it. Does the new version of SpringBoot have Bug?
Obviously, mature frameworks don't make mistakes in this general direction, so could the new version of SpringBoot reverse the order of @ After and @ Around?
In fact, it's not that simple.
Spring AOP execution order
Let's first review the order of Spring AOP execution.
We look up information on the order of SpringAop execution on the Internet, and most of the time, you will find the following answer:
Normal situation
Abnormal situation
The case of multiple sections
So @ Around is supposed to precede @ After, but in the SprinBoot 2.3.4.RELEASE version, @ Around actually executes after @ After.
When I tried to switch back to the 2.2.5.RELEASE version, the execution order went back to @ Around-- > @ After
Explore the truth of the wrong order
Now that you know that the problem (or order change) is caused by the SpringBoot version upgrade, it's time to see which library has changed the order in which AOP executes. After all, SpringBoot is just "shape" and the real kernel is Spring.
We open the pom.xml file, use the plug-in to check the version of spring-aop, and find that the AOP used by the SpringBoot 2.3.4.RELEASE version is spring-aop-5.2.9.RELEASE.
And 2.2.5.RELEASE corresponds to spring-aop-5.2.4.RELEASE.
So I went to the official website to search for documents. I have to say that Spring is so large that the documents on the official website have reached the point of complexity, but I finally found it:
Https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/spring-framework-reference/core.html#aop-ataspectj-advice-ordering
As of Spring Framework 5.2.7, advice methods defined in the same @ Aspect class that need to run at the same join point are assigned precedence based on their advice type in the following order, from highest to lowest precedence: @ Around, @ Before, @ After, @ AfterReturning, @ AfterThrowing.
Let me make a superficial translation of the main points:
Starting with Spring5.2.7, in the same @ aspect class, notification methods are executed in the highest-to-lowest priority based on their type: @ Around,@Before, @ After,@AfterReturning,@AfterThrowing.
From this point of view, the comparison is not obvious. Let's go back to the old version, that is, the spring-aop-5.2.4.RELEASE corresponding to 2.2.5.RELEASE. The document at that time was written as follows:
What happens when multiple pieces of advice all want to run at the same join point? Spring AOP follows the same precedence rules as AspectJ to determine the order of advice execution. The highest precedence advice runs first "on the way in" (so, given two pieces of before advice, the one with highest precedence runs first). "On the way out" from a join point, the highest precedence advice runs last (so, given two pieces of after advice, the one with the highest precedence will run second)
Simple translation: in the same @ Aspect class, Spring AOP follows the same priority rules as AspectJ to determine the order in which advice is executed.
Dig a little deeper, so what are the priority rules for AspectJ?
I looked for AspectJ's documentation:
Https://www.eclipse.org/aspectj/doc/next/progguide/semantics-advice.html
At a particular join point, advice is ordered by precedence.
A piece of around advice controls whether advice of lower precedence will run by calling proceed. The call to proceed will run the advice with next precedence, or the computation under the join point if there is no further advice.
A piece of before advice can prevent advice of lower precedence from running by throwing an exception. If it returns normally, however, then the advice of the next precedence, or the computation under the join pint if there is no further advice, will run.
Running after returning advice will run the advice of next precedence, or the computation under the join point if there is no further advice. Then, if that computation returned normally, the body of the advice will run.
Running after throwing advice will run the advice of next precedence, or the computation under the join point if there is no further advice. Then, if that computation threw an exception of an appropriate type, the body of the advice will run.
Running after advice will run the advice of next precedence, or the computation under the join point if there is no further advice. Then the body of the advice will run.
Everyone is going to say again, Oh, it's too long to look! In short, the rules of Aspectj are the same as shown in the sequence diagram we can see online, which is still the old order.
Code verification
I removed the business logic from the code and only verified the execution order of these advice:
/ * log aspect * / @ Aspect @ Component public class WebLogAspect {private final static Logger LOGGER = LoggerFactory.getLogger (WebLogAspect.class); / * * take all requests defined under the controller package as the entry point * / @ Pointcut ("execution (public * com.xx.xxx.xxx.controller..*.* (..)") Public void webLog () {} / * * weave * @ param joinPoint * @ throws Throwable * / @ Before ("webLog ()") public void doBefore (JoinPoint joinPoint) throws Throwable {LOGGER.info ("- doBefore-") before the pointcut } @ AfterReturning ("webLog ()") public void afterReturning () {LOGGER.info ("- afterReturning-");} @ AfterThrowing ("webLog ()") public void afterThrowing () {LOGGER.info ("- afterThrowing-") } / * * weave * @ throws Throwable * / @ After ("webLog ()") public void doAfter () throws Throwable {LOGGER.info ("- doAfter-") after the pointcut } / * surround * @ param proceedingJoinPoint * @ return * @ throws Throwable * / @ Around ("webLog ()") public Object doAround (ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long startTime = System.currentTimeMillis (); LOGGER.info ("- doAround before proceed-") Object result = proceedingJoinPoint.proceed (); LOGGER.info ("- doAround after proceed-"); return result;}
We changed the version to 2.2.5.RELEASE, and the result is as follows:
We changed the version to 2.3.4.RELEASE, and the result is as follows:
This is the end of the content of "what is the order of execution of Spring AOP". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
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: 269
*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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.