欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > springboot知识点以及源码解析(2)

springboot知识点以及源码解析(2)

2025/3/10 1:02:17 来源:https://blog.csdn.net/2301_79985750/article/details/146101687  浏览:    关键词:springboot知识点以及源码解析(2)

web开发--静态规则与定制化

springboot对静态资源的映射规则:在类路径下面定义目录static或public或resources或者META-INF/resources,访问时项目根目录+静态资源的名称

在springboot中,如果项目中存在同名的静态资源和同名的动态资源。那么我们会优先去访问动态资源,如果动态资源不存在,然后再去访问对应的静态资源,如果静态资源也找不到,那么就报404 的异常 ,为了解决这个问题。

  1. 可以在配置文件中自定义静态资源的映射规则,例如:spring.mvc.static-path-pattern=/resources/**,那么访问静态资源时根目录+resources+静态资源名称。
  2. 也可以给静态资源设置自定义的存放目录:例如spring:web:resourcesstatic-locations:[classpath:/hello/],那么在资源下创建hello这个文件夹,下面放静态资源
  3. 我们也可以访问webjars的资源(webjars 就是将静态资源打成jar包。)
    1、引入相关静态资源的jar包(依赖)
    <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId)
    <version>3.5.1</version>
    </dependency>
    2、通过官方给定的访问路径去访问里面的资源
    http://localhost:8082/webjars/jquery/3.5.1/jquery.js

静态资源和首页映射规则底层原理

源码

webMvcAutoConfiguration底层是如何进行装配的。在org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration中的注解

 在这个类中,主要看WebMvcAutoConfigurationAdapter,是WebMvc自动配置的适配器,

看下面的这个方法 WebMvcAutoConfigurationAdapter,它是一个构造方法,参数从哪里来?

public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {this.resourceProperties = webProperties.getResources();this.mvcProperties = mvcProperties;this.beanFactory = beanFactory;this.messageConvertersProvider = messageConvertersProvider;this.resourceHandlerRegistrationCustomizer = (ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.dispatcherServletPath = dispatcherServletPath;this.servletRegistrations = servletRegistrations;}
  • WebProperties 和 WebMvcProperties:被SpringBoot自动创建并填充到配置文件中,通过@EnableConfigurationProperties注解进行引入,上面图片可以看到
  • ListableBeanFactory: 代表了一个可以列出所有已注册bean定义的bean工厂。它是Spring IoC容器的一部分,不需要特别指定,Spring会自动将其传递给需要它的bean。

  • ObjectProvider<HttpMessageConverters> 和 ObjectProvider<ResourceHandlerRegistrationCustomizer>: 这两个 ObjectProvider 是用来延迟加载特定类型的bean的。如果Spring上下文中存在类型为 HttpMessageConvertersResourceHandlerRegistrationCustomizer 的bean,那么它们就会被注入到这里。如果没有找到匹配的bean,也不会导致错误,因为 ObjectProvider 支持可选的依赖项

  • ObjectProvider<DispatcherServletPath> 和 ObjectProvider<ServletRegistrationBean<?>>: 类似地,这两个也是 ObjectProvider 实例,用于提供对 DispatcherServlet 路径和 ServletRegistrationBean 的访问。如果有相应的bean存在于上下文中,它们将会被注入。

那么适配器初始化这些信息后,那么静态资源是如何生效的?

静态资源是如何生效的

在这个类(

public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware 

)下,有一个addResourceHandlers方法,下面进行图解。

也可以点进去,可以得到

 欢迎页

在WelcomePageHandlerMapping类下的WelcomePageHandlerMapping方法中

WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) {this.setOrder(2); // 优先级为 2。// 确定是否有可用的欢迎页面WelcomePage welcomePage = WelcomePage.resolve(templateAvailabilityProviders, applicationContext, indexHtmlResource, staticPathPattern);if (welcomePage != WelcomePage.UNRESOLVED) { // 如果找到了欢迎页面// 根据欢迎页面是否为模板,记录日志logger.info(LogMessage.of(() -> {return !welcomePage.isTemplated() ? "Adding welcome page: " + String.valueOf(indexHtmlResource) : "Adding welcome page template: index";}));// 创建一个新的实例,可以指定视图名称ParameterizableViewController controller = new ParameterizableViewController();// 设置控制器的视图名称为欢迎页面的视图名称controller.setViewName(welcomePage.getViewName());// 将创建的控制器设置为此 HandlerMapping 的根处理器this.setRootHandler(controller);}
}

springboot中rest请求处理原理

@RestController
public class HelloController {@RequestMapping(value = "/hello",method = RequestMethod.GET)public String sayHello(){return "Hello World!";}
}

在非 REST 风格的传统代码中,为了执行数据的增删改查操作,通常需要将每个操作映射到不同的路径上。然而,采用 REST 风格后,可以使用相同的路径来表示同一个资源,并通过不同的 HTTP 方法(如 POST 用于创建,GET 用于查询,PUTPATCH 用于更新,以及 DELETE 用于删除)来区分这些操作。这样,我们就可以通过单一的端点路径结合适当的请求方法来管理资源,从而提高 API 的清晰度和可维护性。例如,在 Spring MVC 中,你可以通过 @RequestMapping 注解的 method 属性指定支持的 HTTP 方法类型,或者直接使用简化的组合注解如 @GetMapping, @PostMapping, @PutMapping, 和 @DeleteMapping 来实现这一点。同时,@RequestMapping 注解中的 pathvalue 属性互为别名,都可以用来指定请求路径。这样的设计有助于构建更加简洁、一致的服务接口。

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@RequestMapping(value = "user",method = RequestMethod.GET)public String get(){return "Hello User Get!";}@RequestMapping(value = "user",method = RequestMethod.POST)public String post(){return "Hello User Post!";}@RequestMapping(value = "user",method = RequestMethod.PUT)public String put(){return "Hello User Put!";}@RequestMapping(value = "user",method = RequestMethod.DELETE)public String delete(){return "Hello User Delete!";}
}// demo1.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="/user" method="get"><input value="GET提交" type="submit"></form><form action="/user" method="post"><input value="Post提交" type="submit"></form><form action="/user" method="post"><input value="Put提交" type="submit"></form><form action="/user" method="post"><input value="Delete提交" type="submit"></form>
</body>
</html>

由于表单中只能由get和post,没有put和delete,因此它们用post进行代替。设想点击不同的按钮进入不同的表单页,显示不同的值,是这样吗?来看下结果,结果显示:对于get和post提交是正常的,但是对于put和delete提交显示的是Hello User Post!这是由于表单中只能由get和post,为了弄清楚它,回到D:\java\mvn_repository\org\springframework\boot\spring-boot-autoconfigure\3.4.3\spring-boot-autoconfigure-3.4.3.jar!\org\springframework\boot\autoconfigure\web\servlet\这个路径下的WebMvcAutoConfiguration.class类中。过滤器默认不开启,开启需要添加配置文件

在HiddenHttpMethodFilter中,有一个doFilterInternal方法,

进行debug,先发送get请求,进不到if,执行filterChain.doFilter((ServletRequest)requestToUse, response);进行放行

 下面看下post请求,其中this.methodParam是一个_method参数,需要在html文件中进行配置

下面看下加上_method的put请求,delete同理

 注意:下面两者等价 

@RequestMapping(value = "user",method = RequestMethod.GET)
@GetMapping("user")

springboot处理器映射器工作原理

        在SpringMVC中有一个组件DispatcherServlet,在DispatcherServlet.class这个类下,它是用于处理前端用户的请求。体系结构如下:

进入FrameworkServlet中,有doGet,doPost,doPut和doDelete,它们四个处理Http请求,这四个方法都调用了processRequest方法,在processRequest方法中,首先进行一些初始化,然后在doService方法中提供服务,doService方法中又有doDispatch方法,这个方法中关注这句话:mappedHandler = this.getHandler(processedRequest);

 

如果是不大于1的话: 

总结:用户的请求交给DispatcherServlet前端控制器中的doDispatch方法进行处理,其中被doDispath方法中的getHandler获取想要的handler对象,这个handler对象被包装到HandlerExecutionChain里面。那么handler如何被获取?mappedHandler=this.getHandler(processedRequest)方法帮助处理,this.getHandler内部,有5个映射器,RequestMappingHandlerMapping处理被@RequestMapping注解修饰的处理器方法,返回一个handler。这个handler最终交给处理器适配器进行处理。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词