Spring MVC configuration and underlying principles
-
Import spring MVC jar package
-
Configure the total (front-end) controller web.xml
-
Add spring MVC configuration file src/appContext.xml
-
Write Controller and handle connection and method
The imitation of the underlying principle of spring MVC
1) . import jar package to parse xml document
2) . write a MyDispatcherServlet to complete the loading and runtime functions of the DispatcherServlet of the spring MVC front-end controller:
Load appContext.xml file when the server starts
Notes on writing MyDispatcherServlet class
/ / loading time /* url interface corresponding class method string (urlStrMap) is saved in application 1. /fff.do com.senchen.controller.FirstController#f1 /sss.do com.senchen.controller.SecondController#s1 2. The reflection type is saved in a spring container Map application Key (COM. Senchen. Controller. Firstcontroller) value (instance) */
1. Get the name of the spring MVC configuration file
String fileName = getInitParameter("ccc");
2. Get the project path
System.out.println("1.." + getServletContext().getRealPath("")); //Current project path System.out.println("1.." + getServletContext().getRealPath("/")); //Current project path System.out.println("2.." + this.getClass().getResource("").getPath()); //Current classpath System.out.println("2.." + this.getClass().getResource("/").getPath()); //The classes directory of the current project, with a ':'
3. Remove: determine the location of the spring MVC configuration file
String webPath = this.getClass().getResource("/").getPath().substring(1); String xmlPath=""; if( fileName.toLowerCase().startsWith( "classpath")){ xmlPath = webPath + fileName.substring( fileName.indexOf(":")+1 ); // }else if( fileName.toLowerCase().startsWith("/web-inf")){ xmlPath = getServletContext().getRealPath("")+fileName; }else { xmlPath = fileName; } System.out.println(fileName+"!!!Journal 1.Read on startup xml Directory location: "+ xmlPath);
4. Place urlStrMap and spring instance containers
//url and corresponding string collection Map<String,String> urlStrMap = new HashMap<String, String>(); this.getServletContext().setAttribute("URLMap", urlStrMap); //application.setAttribute //handlerMapping //spring container collection Map<String,Object> springIoc = new HashMap<String, Object>(); this.getServletContext().setAttribute("springMap", springIoc);//application.setAttribute //web_application_context_attribute
5. Read the XML document to obtain
url->fff
classPath->com.senchen.controller.FirstController
mdName->f1
<bean name="fff" class="com.senchen.controller.FirstController" method="f1"/>
Put the key in urlStrMap: url, value: clspath + "×" + mdname method
Put the key: url, value: Class.forName(clsPath) instance object in springIoc
//Read xml document SAXBuilder saxBuilder = new SAXBuilder(); InputStream in; try { // 1. Create an input stream and load the xml file into the input stream in = new FileInputStream( xmlPath ); InputStreamReader isr = new InputStreamReader(in, "UTF-8"); // 2. Load the input stream into saxBuilder through saxBuilder's build method Document document = saxBuilder.build(isr); // 3. Get the root node of the xml file through the document object Element rootElement = document.getRootElement(); System.out.println("!!!Journal 2...xml root:" + rootElement.getName() ); // 4. Get the List set of child nodes under the root node List<Element> firstList = rootElement.getChildren(); for(Element bn :firstList){ String url = bn.getAttributeValue("name").trim(); String clsPath = bn.getAttributeValue("class").trim(); String mdName = bn.getAttributeValue("method").trim();; System.out.println("!!!Journal 3...Mapped URL path ["+url+"] onto handler '"+clsPath+"'"); urlStrMap.put(url, clsPath+"#"+mdName); //urlMap springIoc.put(url, Class.forName(clsPath).newInstance()); //spring instance Map
Role of runtime
/ / runtime /* A. Running Dispatcher receives a. do request B. Intercept / fff.do C. Find urlStrMap in application Get the type string and method f1 D. Find the instance corresponding to the type string in the spring container in the application E.f1.invoke */
1. Receive request.getrequesturi/. Do request example tj1.1/fff.do
2. Intercept the url between '/' and '.'
String start = coming.substring( coming.lastIndexOf("/")+1 , coming.lastIndexOf(".") );
3. Get the spring container collection from the ServletContext domain to get the instance object
Map<String,Object> spMap = (Map)this.getServletContext().getAttribute("springMap"); Object controller = spMap.get( start ); // fff
Get the URLMap set from the ServletContext domain and get the full class name and method name by '#'
Map<String,String> urlMap = (Map)this.getServletContext().getAttribute("URLMap"); String claMd = urlMap.get( start ); // com.senchen.controller.FirstController#f1 String clsName = claMd.substring(0, claMd.lastIndexOf("#")); //com.senchen.controller.FirstController String methodName = claMd.substring( claMd.lastIndexOf("#")+1 ); //f1 System.out.println("+++Journal 3..urlMap Remove class "+clsName +" Method" + methodName);
4. Get object type through reflection and full class name
Get method by type, method name, reflection
Method. Invoke (instance object) execution method
//Reflection type Class clxx = Class.forName( clsName ); //Reflection method Method md = clxx.getMethod( methodName ); //Call method to receive return value Object ret = md.invoke( controller );
5. Determine whether to redirect the returned processing
//Return processing if( null !=ret ){ String retView = (String)ret; if( retView.startsWith("redirect")){ //redirect response.sendRedirect( request.getContextPath() + retView.substring( retView.lastIndexOf(":")+1 ) ); }else{ //Forward request.getRequestDispatcher( retView ).forward(request, response); } }
6.appContext.xml configuration file
No notes
Annotate
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.senchen.controller"/> <!-- url Interface Corresponding class method string(urlStrMap)Save to application in 1. /fff.do com.senchen.controller.FirstController#f1 /sss.do com.senchen.controller.SecondController#s1 2. The reflection type is saved in a spring container Map in application in key(com.senchen.controller.FirstController) value( Example ) A.Function Dispatcher Receive .dorequest B.Intercept /fff.do C.look for application Medium urlStrMap //Get the type string and method f1 D.look for application Medium spring Instance corresponding to type string in container E.f1.invoke --> <!-- Try parser springMVC Managerial jsp File location should be in /WEB-INF/meto/ --> <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/meto/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
Summary
When the server starts, the name of the appContext.xml configuration file is saved in < param name > XXX < / param name > XXX, and the mydispatcherseservlet class also loads the init method to get the configuration file name, and finally gets the file path, and then parses the XML file to get the url: access path, clsPath: class's fully qualified name, mdName: method name, Save them in two Map collections, with instance objects in the Spring container
urlStrMap.put(url, clsPath+"#"+mdName); //urlMap springIoc.put(url, Class.forName(clsPath).newInstance() ); //spring instance Map
The above is imitating handler mapping
During access, the service method intercepts the access path into the url string in the collection, obtains the corresponding full class name, method name and instance object, and then obtains the object type and method through reflection, and executes it,
For the return value, you can judge whether to redirect or forward according to the returned string truncation
This is the analog processor adapter HandlerAdapter