你对SpringMVC了解多少呢?SpringMVC可以说得上是当前最优秀的MVC框架,采用了松散耦合可插拔组件结构,比其他MVC框架更具扩展性和灵活性;为了提高框架的扩展性和灵活性,设计了松耦合可插拔的组件。理解SpringMVC的原理,在面试或工作中都十分的重要。
SpringMVC的原理在网络上到处都可以找得到,但是写得都很概括、零散;对应阅读源码经验较少的小伙伴来说,自己去看源码被很多细节所干扰阻碍,不能够很好地抽离出springMVC原理的主线。
下面就给大家分享一下LZ整理的有关SpringMVC的学习资料,学会用代码说话!
1.1、创建Maven工程
2.1、pom依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhz</groupId><artifactId>simulation-springmvc</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>simulation-springmvc Maven Webapp</name><!-- FIXME change it to the project's website --><url>;/url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><mavenpiler.source>1.7</mavenpiler.source><mavenpiler.target>1.7</mavenpiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>org.apachemons</groupId><artifactId>commons-lang3</artifactId><version>3.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><dependency><groupId>com.</groupId><artifactId>jackson-databind</artifactId><version>2.9.1</version></dependency></dependencies><build><finalName>simulation-springmvc</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see .html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build>
</project>
2.2、springmvc配置类
<?xml version="1.0" encoding="UTF-8" ?>
<beans><!--配置创建容器时要扫描的包--><component-scan base-package="ller,com.zhz.service"></component-scan>
</beans>
2.3、l
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"".dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--配置前端控制器--><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>com.zhz.springmvc.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>l</param-value></init-param><!--Web服务器一旦启动,Servlet就会实例化创建对象,然后初始化(预备创建对象)--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>
实体类:User.java
package com.zhz.bean;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author :zhz* @date :Created in 2021/01/04* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 实体类**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;private String password;
}
package ller;import com.zhz.bean.User;
import com.zhz.service.UserService;
import com.zhz.springmvc.annotation.Autowired;
import com.zhz.springmvc.annotation.Controller;
import com.zhz.springmvc.annotation.RequestMapping;
import com.zhz.springmvc.annotation.ResponseBody;/*** @author :zhz* @date :Created in 2021/01/03* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 控制器**/
@Controller
public class UserController {@Autowired(value = "userService")private UserService userService;@RequestMapping("/listUsers")public String listUsers(){userService.listUsers();return "forward:/success.jsp";}@RequestMapping("/getData")@ResponseBody //返回json格式的数据public User getData(){//调用服务层User();}
}
package com.zhz.service;import com.zhz.bean.User;/*** @author :zhz* @date :Created in 2021/01/03* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description:**/
public interface UserService {void listUsers();User getUser();
}
package com.zhz.service.impl;import com.zhz.bean.User;
import com.zhz.service.UserService;
import com.zhz.springmvc.annotation.Service;/*** @author :zhz* @date :Created in 2021/01/03* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description:**/
@Service("userService")
public class UserServiceImpl implements UserService {@Overridepublic void listUsers() {System.out.println("===调用===UserServiceImpl===listUser===");}@Overridepublic User getUser() {return new User(1,"zhz","123456");}
}
6.1、核心annotation注解
package com.zhz.springmvc.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @Retention注解表示Annotation的保留策略 RetentionPolicy.Class:运行时不保留,不可以通过反射读取。* RetentionPolicy.RUNTIME:运行是保留,可以通过反射读取。* RetentionPolicy.SOURCE:丢弃。*/
@Target(value = ElementType.FIELD) //作用在属性上
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Autowired {String value();
}
package com.zhz.springmvc.annotation;import java.lang.annotation.*;@Target(ElementType.TYPE) // //作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {String value() default "";
}
package com.zhz.springmvc.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD) //作用在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {String value() default "";
}
package com.zhz.springmvc.annotation;import java.lang.annotation.*;/*** @BelongsProject: SpringMvc*/
@Target(ElementType.METHOD) //作用在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
package com.zhz.springmvc.annotation;import java.lang.annotation.*;/*** @Description: 自定义注解*/
@Target(ElementType.TYPE) //作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {String value();
}
6.2、context上下文(SpringMVC容器)
package com.t;import com.zhz.springmvc.annotation.Autowired;
import com.zhz.springmvc.annotation.Controller;
import com.zhz.springmvc.annotation.Service;
import com.l.XmlParse;import java.io.File;
import flect.Field;
import java.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import urrent.ConcurrentHashMap;/*** @author :zhz* @date :Created in 2021/01/03* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: SpringMVC容器**/
public class WebApplicationContext {//lString contextConfigLocation;//定义集合 用于存放 bean 的权限名|包名.类名List<String> classNameList = new ArrayList<>();//创建Map集合用于扮演IOC容器: key存放bean的名字 value存放bean实例public Map<String, Object> iocMap = new ConcurrentHashMap<>();public WebApplicationContext() {}public WebApplicationContext(String contextConfigLocation) {tConfigLocation = contextConfigLocation;}/*** 初始化Spring容器*/public void onRefresh() {//1、进行解析spring mvc配置文件操作 ==》 ller,com.zhz.serviceString basePackage = BasePackage(contextConfigLocation.split(":")[1]);//通过","来分割ller,com.zhz.service 获得对应的包名String[] packs = basePackage.split(",");//2、进行包扫描for (String pack : packs) {executeScanPackage(pack);}//3、实例化容器中的beanexecuteInstance();//4、进行自动注入操作executeAutowired();}/*** 进行包扫描** @param pack*/private void executeScanPackage(String pack) {//1、把ller====>com/zhz/controller com.zhz.service====>com/zhz/controllerURL url = Class().getClassLoader().getResource("/" + placeAll("\.", "/"));String path = File();//2、/com/zhz/serviceFile dir = new File(path);for (File file : dir.listFiles()) {if (file.isDirectory()) {//说明是com.zhz.service.impl层executeScanPackage(pack + "." + Name());} else {//文件目录下文件 获取全路径 UserController.class ==> ller.UserControllerString className = pack + "." + Name().replaceAll(".class", "");classNameList.add(className);}}}/*** 实例化容器*/private void executeInstance() {try {// ller.UserController com.zhz.service.impl.UserServiceImplfor (String className : classNameList) {Class<?> clazz = Class.forName(className);if (clazz.isAnnotationPresent(Controller.class)) {//控制层的bean,得到类的简写名称也就是UserControllerString beanName = SimpleName().substring(0, 1).toLowerCase()SimpleName().substring(1);//首位变为小写iocMap.put(beanName, wInstance());} else if (clazz.isAnnotationPresent(Service.class)) {//Service层,主要是为了获得他的valueService service = Annotation(Service.class);String beanName = service.value();iocMap.put(beanName, wInstance());}}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}/*** 进行自动注入操作*/private void executeAutowired() {try {//从容器中取出bean,然后判断bean中是否有属性上使用Autowired,如果使用了该注解,就需要进行自动注入操作for (Map.Entry<String, Object> entry : Set()) {//取出容器中的beanObject bean = Value();//从bean中获取属性Field[] fields = Class().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(Autowired.class)) {//获取注解中的value值,该值是bean的nameAutowired autowired = Annotation(Autowired.class);String beanName = autowired.value();;//取消检查机制field.setAccessible(true);field.set(bean, (beanName));}}}} catch (IllegalAccessException e) {e.printStackTrace();}}
}
6.3、映射处理(url与ccontroller之间的映射)
package com.zhz.springmvc.handler;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import flect.Method;/*** @author :zhz* @date :Created in 2021/01/04* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description:**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HandlerMapping {//请求URL地址private String url;//控制器private Object controller;//控制器的方法private Method method;
}
6.4、前端处理器
package com.zhz.springmvc.servlet;import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhz.springmvc.annotation.Controller;
import com.zhz.springmvc.annotation.RequestMapping;
import com.zhz.springmvc.annotation.ResponseBody;
import com.t.WebApplicationContext;
import com.zhz.springmvc.handler.HandlerMapping;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import flect.InvocationTargetException;
import flect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** @author :zhz* @date :Created in 2021/01/03* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 前端控制器**/
public class DispatcherServlet extends HttpServlet {//指定SpringMvc容器private WebApplicationContext webApplicationContext;//创建集合,用于存放映射关系、映射地址与控制器.方法,用于发送请求直接从该集合中进行匹配List<HandlerMapping> handList = new ArrayList<>();@Overridepublic void init() throws ServletException {//1、从l中获得加载初始化参数contextConfigLocation的值lString configLocation = ServletConfig().getInitParameter("contextConfigLocation");//2、创建SpringMVC容器webApplicationContext = new WebApplicationContext(configLocation);//3、进行初始化操作Refresh();//4、初始化请求映射关系 /findUser ===》控制器.方法initHandlerMapping();}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//进行请求分发处理doDispatcher(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}/*** 初始化请求映射关系(获取链接地址0*/private void initHandlerMapping() {//遍历map, key存放bean的名字 value存放bean实例for (Map.Entry<String, Object> entry : Set()) {//获得bean的class类型Class<?> clazz = Value().getClass();if (clazz.isAnnotationPresent(Controller.class)) {//获取bean中所有的方法,为这些方法建立映射关系Method[] methods = DeclaredMethods();for (Method method : methods) {if (method.isAnnotationPresent(RequestMapping.class)) {RequestMapping requestMapping = Annotation(RequestMapping.class);//获取注解中的值String url = requestMapping.value();//建立映射地址,与控制器 方法HandlerMapping handlerMapping = new HandlerMapping(url, Value(), method);handList.add(handlerMapping);}}}}}/*** 进行请求分发处理** @param request* @param response*/private void doDispatcher(HttpServletRequest request, HttpServletResponse response) {try {//根据用户的请求地址(/listUsers)查找ControllerHandlerMapping handlerMapping = getHandler(request);if (handlerMapping == null) {Writer().print("<h1>404 NOT FOUND!</h1>");} else {//调用处理方法之前 进行参数的注入//调用目标方法---》获得方法的返回值类型Object result = Method().Controller());if (result instanceof String){//跳转到JSP中String viewName = (String)result;//forward:/success.jsp重定向if (ains(":")){String viewType=viewName.split(":")[0];//也就是forward或者redirectString viewPage=viewName.split(":")[1];//跳转的页面if (viewType.equals("forward")){//请求转发RequestDispatcher(viewPage).forward(request,response);}else{//重定向response.sendRedirect(viewPage);}}else{//默认请求转发RequestDispatcher(viewName).forward(request,response);}}else{//返回JSON格式数据Method methodMethod();if (method.isAnnotationPresent(ResponseBody.class)){//将返回值转换成 json格式数据ObjectMapper objectMapper = new ObjectMapper();String json = objectMapper.writeValueAsString(result);response.setContentType("text/html;charset=utf-8");PrintWriter writer= Writer();writer.print(json);writer.flush();writer.close();}}}} catch (IOException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (ServletException e) {e.printStackTrace();}}/*** 根据用户请求查找对应的Handler======>获取请求对应的handler(也就是从handList中取出)** @param request* @return*/private HandlerMapping getHandler(HttpServletRequest request) {String requestURI = RequestURI();for (HandlerMapping handlerMapping : handList) {//从容器的Handle取出URL 和 用户的请求地址进行匹配,找到满足条件的Handler(controller)if (Url().equals(requestURI)) {return handlerMapping;}}return null;}}
6.5、解析XML
package com.l;import lombok.val;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.File;
import java.io.InputStream;/*** @author :zhz* @date :Created in 2021/01/04* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 解析l**/
public class XmlParse {public static String getBasePackage(String xml){try {SAXReader saxReader=new SAXReader();// 通过reader对象的read方法加载l文件,获取docuemnt对象。InputStream inputStream = ClassLoader().getResourceAsStream(xml);Document document = ad(inputStream);// 通过document对象获取根节点beansElement rootElement = RootElement();// 通过element对象的返回给定本地名称和任何名称空间的第一个元素Element componentScan = rootElement.element("component-scan");//返回componentScan的参数Attribute attribute = componentScan.attribute("base-package");//返回base-package的值String basePackage = Text();return basePackage;} catch (DocumentException e) {e.printStackTrace();}return "";}
}
7.1、index.jsp
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
7.2、succes.jsp
<html>
<body>
<h2>Hello World!</h2>跳转至success.jsp页面
</body>
</html>
这篇关于手撕springMVC的文章就先更到这里了,感谢你看到这里,文章有什么不足还请指正,觉得文章对你有帮助的话记得给我点个赞,SpringMVC其实并不算是一个很难的知识点,用点心多看就很简单
每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!
原文链接:
本文发布于:2024-01-31 12:30:37,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170667543728527.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |