In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the knowledge of "should RequestMapping be written in the Controller class?". In the operation of actual cases, many people will encounter such a dilemma. Next, 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!
Students who use Spring Cloud as a project will use Feign as a component to make remote service calls. Feign uses templates and has an elegant code-writing specification. The core principle parses the Feign and other related annotations, and extracts the information. When the Spring Boot project starts, it reflects the bean of the production Request, and sets the extracted information into bean, and finally injects it into the ioc container.
Now there is a scenario in which Service An improves the RestApi interface, and services such as Service B, C, D need to call the RestApi interface provided by Service A. the most common way is to write a FeignClient in Service B, C, D, and need to write the entity that receives the parameters of the RestApi interface and the entity DTo class that receives the response. The way to do this is to keep copying the code.
Is there any way to simplify the above operation? One of the most common practices is to split Service An into modules and write a separate module between FeignClient and the common classes exported by model and dto, which can be similar to naming a-service-open_share. In this way, the service A service is divided into two modules, namely, the business module of the A service and the module of the public class that the A service needs to be referenced by other services. Services B, C, D only need to reference the a-service-open_share of Service A to have the ability to invoke Service A.
The author has encountered an interesting problem here. First of all, let's look at the problem:
Write a FeignClient:
@ FeignClient (name = "user-service") public interface UserClient {@ GetMapping ("/ users") List getUsers ()
Write an implementation class:
@ RestControllerpublic class UserController implements UserClient {@ Autowired UserService userService; @ OverRide List getUsers () {return userService.getUsers ();}
Start the project, the browser access interface localhost:8008/users, unexpectedly can correctly access?! Obviously I didn't add RequestMapping to the getUsers method of the UserController class. Why can you map correctly?!
With such doubts, I carried out some analysis and exploration!
First of all, I wrote a demo, and first created an interface class:
Public interface ITest {@ GetMapping ("/ test/hi") public String hi ();}
Write a Controller class TestController
@ RestControllerpublic class TestController implements ITest {@ Override public String hi () {return "hi you!";}
Start the project, browser access: http://localhost:8762/test/hi, browser display:
Hi you!
I'll go. Can the TestController method hi () get the @ GetMapping ("/ test/hi") annotation of ITest's method hi ()? The answer is definitely not available.
Specially compiled the TestController bytecode file:
Javap-c TestController
Public class com.example.demo.web.TestController implements com.example.demo.web.ITest {public com.example.demo.web.TestController (); Code: 0: aload_0 1: invokespecial # 1 / / Method java/lang/Object. "": () V 4: return public java.lang.String hi () Code: 0: ldc # 2 / / String hi you! 2: areturn}
The bytecode above doesn't have any information about @ GetMapping ("/ test/hi"), so TestController can't get the information about @ GetMapping ("/ test/hi") directly.
That should be handled by Spring MVC when injecting Controller's Bean (HandlerAdapter) into the container at startup. The preliminary judgment should be to obtain this information through reflection and assemble it into the Bean of Controller. First of all, let's see if the annotation information of ITest can be obtained through reflection:
Public static void main (String [] args) throws ClassNotFoundException {Class c = Class.forName ("com.example.demo.web.TestController"); Class [] i=c.getInterfaces (); System.out.println ("start interfaces.."); for (Class clz:i) {System.out.println (clz.getSimpleName ()); Method [] methods = clz.getMethods () For (Method method: methods) {if (method.isAnnotationPresent (GetMapping.class)) {GetMapping w = method.getAnnotation (GetMapping.class); System.out.println ("value:" + w.value () [0]);}} System.out.println ("end interfaces.."); Method [] methods = c.getMethods () For (Method method: methods) {if (method.isAnnotationPresent (GetMapping.class)) {GetMapping w = method.getAnnotation (GetMapping.class); System.out.println ("value:" + w.value ());}
Allow the above code to be run:
Start interfaces..
ITest
Value:/test/hi
End interfaces..
It can be seen that the TestController class can get the annotation information of the interface it implements through reflection. In order to verify that when Spring Mvc injects the bean of Controller, the annotation information of its implemented interface is obtained by reflection and mapped as urlMapping. So I looked at the source code of Spring Mvc, and after a series of tracing, I found the following methods in the RequestMappingHandlerMapping.java class:
Protected RequestMappingInfo getMappingForMethod (Method method, Class handlerType) {RequestMappingInfo info = createRequestMappingInfo (method); if (info! = null) {RequestMappingInfo typeInfo = createRequestMappingInfo (handlerType); if (typeInfo! = null) {info = typeInfo.combine (info);}} return info;}
Continue to trace the source code and find the following code snippet in the searchWithFindSemantics () method of the AnnotatedElementUtils class:
/ / Search on methods in interfaces declared locallyClass [] ifcs = method.getDeclaringClass (). GetInterfaces (); result = searchOnInterfaces (method, annotationType, annotationName, containerType, processor, visited, metaDepth, ifcs); if (result! = null) {return result;}
This is the code snippet I'm looking for, validating my guess.
This is the end of the content of "RequestMapping should be written in the Controller class". Thank you for 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: 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.
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.