In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Editor to share with you how to use springmvc, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's learn about it!
1. Configuration stage
According to web.xml, first define the DispatcherServlet and define the parameters and paths passed in by the sevlet.
two。 Initialization phase
The initialization phase can be divided into IOC, DI, and MVC phases:
(1) IOC: initialize the configuration file and IOC container, scan the classes under the configured package, and put the classes that need to be instantiated into the IOC container through the reflection mechanism, that is, the classes with spring annotations are instantiated and stored in the IOC container. The essence of an IOC container is a collection
(2) DI:DI phase (which is actually dependency injection). Assign values to instance properties that need to be assigned (generally dealing with annotated @ Autowrized attributes)
(3) MVC: construct a HandlerMapping set, which is mainly used to store the relationship between API and Method exposed to the public. An API usually corresponds to an executable Method.
3. Operation stage
In the runtime, when a url is received, it goes to the HandleMapping collection, finds the corresponding Method, executes the invoker through the reflection mechanism, and then returns the result to the caller.
This roughly completes the entire run phase of springmvc, and what is described is only a personal point of view. If there is any mistake, please point it out in the comments.
The overall process can be seen in the following figure:
Next, we will try to handwrite a framework similar to springmvc, this handwriting process is quite a sense of achievement!
1. Create an empty JavaWeb project and introduce dependencies. In fact, because we want to write spring by hand, we basically don't need any external dependency tools. We just need to import servlet-api, as follows:
Javax.servlet servlet-api 2.5 provided
two。 According to the process description above, the next step is to configure web.xml:
AppServlet com.wangcw.cwframework.sevlet.CwDispatcherServlet contextConfigLocation application.properties 1 appServlet / *
For CwDispatcherServlet in configuration, you are customizing a Servlet that has the same function as DispatcherServlet in spring. Create an empty CwDispatcherServlet here and inherit javax.servlet.http.HttpServlet. The specific implementation will be described later.
Here because it is part of the function of handwritten spring, so the configuration does not need to write too much, here only take a package scan configuration (scanPackage), you can expand your own.
The configuration file application.properties initialized in CwDispatcherServlet contains the following:
ScanPackage=com.wangcw
3. I believe that another part of the annotations in spring are familiar to everyone, so let's start with these annotations. (the function of each note is not pointed out here. I believe there are already many on Baidu.)
Spring comment Custom Note @ Controller@CwController@Autowired@CwAutowired@RequestMapping@CwRequestMapping@RequestParam@CwRequestParam@Service@CwService
Then implement the following custom comments and paste the code directly:
/ * * create an annotation class similar to @ Controller function * / import java.lang.annotation.*; @ Target ({ElementType.TYPE}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface CwController {String value () default ";} / * * create an annotation class similar to @ Autowried function * / import java.lang.annotation.* @ Target ({ElementType.FIELD}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface CwAutowried {String value () default ";} / * * create an annotation class * / import java.lang.annotation.*; @ Target ({ElementType.TYPE, ElementType.METHOD}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface CwRequestMapping {String value () default" } / * * create an annotation class similar to @ RequsetParam function * / import java.lang.annotation.*; @ Target ({ElementType.PARAMETER}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface CwRequestParam {String value () default ";} / * * create an annotation class similar to @ Service function * / import java.lang.annotation.* @ Target ({ElementType.TYPE}) @ Retention (RetentionPolicy.RUNTIME) @ Documentedpublic @ interface CwService {String value () default "";}
4. Create a simple Demo for the interaction between the control layer and the business layer, plus custom annotations, the function of the specific annotations, which will be described later.
Controller.java
CwController @ CwRequestMapping ("/ demo") public class Controller {@ CwAutowried private Service service; @ CwRequestMapping ("/ query") public void query (HttpServletRequest req, HttpServletResponse resp,@CwRequestParam ("name") String name) throws IOException {resp.getWriter () .write (service.query (name)) } @ CwRequestMapping ("/ add") public void add (HttpServletRequest req, HttpServletResponse resp, @ CwRequestParam ("a") Integer a, @ CwRequestParam ("b") Integer b) throws IOException {resp.getWriter () .write ("aqb=" + (aqb));}}
Service.java
Public interface Service {String query (String name);}
ServiceImpl.java
@ CwServicepublic class ServiceImpl implements Service {@ Override public String query (String name) {return "I am" + name;}}
5. The above controller layer and service layer have used all of our above custom annotations, and then we begin to handwrite the core function of spring, which is to implement CwDispatcherServlet.java, a subclass of HttpServlet.
First of all, we need to override the init method in the parent class, because we want to achieve the same effect as spring in the Init process.
What do you need to do in the process of managing init ()? Sorted out the main steps needed in init ()
@ Override public void init (ServletConfig config) {/ * 1. Load the configuration file * / doLoadConfig (config.getInitParameter ("contextConfigLocation")); / * 2. Scan all related classes * / doScanner (contextConfig.getProperty ("scanPackage")) under the path configured by scanPackage; / * 3. Initialize all associated instances and put them in the IOC container * / doInstance (); / * 4. Implement automatic dependency injection DI*/ doAutowired (); / * 5. Initialize HandlerMapping * / initHandlerMapping ();}
The first step is simple: define a Properties instance in the class to hold the configuration file initialized by Servlet. Skip the import configuration code and read and write IO normally.
Private Properties contextConfig = new Properties ()
The second step is to get the packet path that needs to be scanned through the configuration obtained above, and then find the corresponding folder according to the path and do a recursive scan. Remove the suffix from the scanned file name and save it to a collection that stores the class names of all the classes under the package.
String scanFileDir = contextConfig.getProperty ("scanPackage"); / * used to store the scanned class * / private List classNames = new ArrayList (); / * the corresponding class name is obtained by scanning, which is convenient for reflection to use * / String className = scanPackage + "." + file.getName (). Replace (".class", "); classNames.add (className)
The third step is the IOC phase, which in short iterates through all the classes in the above collection and creates an IOC container that places classes with @ CwController and @ CwService in the container.
/ * create an IOC container * / private Map IOC = new HashMap () For (String classNme: classNames) {if (initialize the class annotated with @ CwController) {/ * for the initialized class, you also need to put it into the IOC container. For the instance stored in IOC, the key value is regular. The default class name is lowercase. * / / * toLowerFirstCase is a custom tool method that lowercase the first letter of the passed string * / String beanName = toLowerFirstCase (clazz.getSimpleName ()); IOC.put (beanName, clazz.newInstance ()) } else if (initialize classes annotated with @ CwService) {/ * for instances stored in IOC, the key value has certain rules, while the rules in the Service layer are more complex than above, because annotations can have custom instance names and may be interface implementation classes * / IOC.put (beanName, instance) } else {/ / ignore the initialization behavior continue;} for unannotated classes scanned
The fourth step is the DI operation, which assigns the instance properties that need to be assigned in the IOC container, that is, the instance properties with Autowired annotations. The pseudo code is as follows:
/ * traverse all instances in IOC * / for (Map.Entry entry: IOC.entrySet ()) {/ * use getDeclaredFields brute force reflection * / Field [] fields = entry.getValue (). GetClass (). GetDeclaredFields (); for (Field field: fields) {/ * 1. Determine whether the attribute is annotated with @ CwAutowried. Only attributes with annotations need to be assigned * /. / * attribute authorization * / field.setAccessible (true); field.set (entry.getValue (), IOC.get (beanName));}}
The fifth step is to deal with the matching relationship between the Method of the Controller layer and the request url, so that the request can be accurately requested to the corresponding url. For the question of space, we are still uploading pseudo code here.
/ * create a matching relationship in which HandlerMapping stores url,method, where class Handler is defined by myself to match url and method using rules. As long as users pass in url,Handler, they can respond to their corresponding method*/ private List handlerMapping = new ArrayList (); / * traverse the IOC container * / for (Map.Entry entry: IOC.entrySet ()) {Class clazz = entry.getValue (). GetClass () / * only classes with CwController annotations are processed * / define a url, which consists of the value of @ CwRequestMapping annotation on the instance class with CwController and the value of @ CwRequestMapping annotation on Method. Determine whether there are CwRequestMapping comments on the class, and splice url*/ / * (2). Traverse each Method under the instance, and need to determine whether the method has [@ CwRequestMapping] annotations. Concatenate url*/ / * and finally put the matching relationship in a regular form into the HandlerMapping set * / String regex = (url); Pattern pattern = Pattern.compile (regex); handlerMapping.add (new Handler (pattern,method));}
At this point, the initialization phase of springmvc is almost complete, and then the work is to rewrite the doGet () / doPost () method of the CwDispatcherServlet.java parent class. The corresponding Method is executed according to the URI and parameters in the request, and the result is responded.
/ * use reflection to execute its matching method * / handler.method.invoke (handler.controller, paramValues)
At this point, the whole step is complete, and you can happily start the project and visit the corresponding url for testing.
According to the method defined by Controller above, we can see that the matching url is / demo/query and / demo/add, and the names of its parameters are defined using the @ CwRequestParam annotation.
The test results are as follows:
Http://localhost:8080/spring/demo/query?name=James
Http://localhost:8080/spring/demo/add?a=222222&b=444444
Let's test a url where the @ CwRequestMapping annotation is not declared in controller. Take a look at the results.
Http://localhost:8080/spring/demo/testNoUrl
SpringMVC introduction and execution process what is SpringMVC?
SpringMVC is a lightweight web layer framework that implements the MVC design pattern and is easy to use.
What are the advantages of SpringMVC?
1. Clear division of roles:
Front-end controller (DispatcherServlet)
Request to processor mapping (HandlerMapping)
Processor Adapter (HandlerAdapter)
View parser (ViewResolver)
Processor or Page Controller (Controller)
Verifier (Validator)
Command object (the object to which the Command request parameter is bound is called the command object)
Form objects (the objects that Form Object provides for form presentation and submission are called form objects).
2. The division of labor is clear, and the extension point is quite flexible, so it can be easily extended, although it is almost unnecessary.
3. Because the command object is a POJO, there is no need to inherit the framework-specific API, you can use the command object directly as a business object.
4. Seamless integration with other Spring frameworks, which other Web frameworks do not have.
5. Adaptable, and any class can be supported as a processor through HandlerAdapter.
6. Customizable, HandlerMapping, ViewResolver and so on can be easily customized.
7. Powerful data validation, formatting and binding mechanisms.
8. Using the Mock object provided by Spring, the unit test of Web layer can be done very simply.
9. Localization and theme parsing support make it easier for us to internationalize and switch themes.
10. Powerful JSP tag library makes it easier to write JSP.
There are also support for RESTful style, simple file upload, contract programming support for conventions greater than configuration, zero configuration support based on annotations, and so on.
Comparison with Struts2:
What they have in common: they are all presentation layer frameworks based on the MVC design pattern, the underlying implementation is inseparable from the original Servlet, and the mechanism for handling requests is a core controller.
Difference: the entrance to Spring MVC is Servlet, while Struts2 is Filter
Spring MVC is designed based on methods, while Struts2 is based on classes, and Struts2 creates an action class for each execution. So Spring MVC will be a little faster than Struts2.
In comparison, SpringMVC has surpassed Struts2 in an all-round way.
Perform the process:
DispatcherServlet: is the core of the entire springmvc framework.
Front controller / core controller: all requests and responses are allocated by this controller.
All the work of the front-end controller is based on components:
Three major components:
HandlerMapping: it is responsible for finding the corresponding hadler according to the client's request, and returning the handler to DispatcherServlet after finding it.
HandlerAdapter: it is responsible for executing the method of finding Handler. After the method is executed, the return value is returned to HandlerAdapter, and HandlerAdapter passes the return value to DispatcherServlet.
ViewResolver: it looks for the corresponding page based on the return result specified by DispatcherServlet, and returns the result to DispatcherServlet after finding it.
DispatcherServlet is responsible for the final response, and the default is the forward operation.
Execution flowchart:
The above is all the contents of the article "how to use springmvc". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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.