当前位置: 首页 > news >正文

wordpress做动漫网站站长工具视频

wordpress做动漫网站,站长工具视频,中央广播电视总台电话,自建html怎么融入wordpress文章目录 前言正文一、设计原理1.1 servlet生命周期简述1.2 设计原理小结 二、启动原理2.1 AbstractHandlerMethodMapping 初始化 --RequestMapping注解解析2.2 DispatcherServlet 的初始化2.3 DispatcherServlet#initHandlerMappings(...) 初始化示例说明 三、工作原理 前言 …

文章目录

  • 前言
  • 正文
    • 一、设计原理
      • 1.1 servlet生命周期简述
      • 1.2 设计原理小结
    • 二、启动原理
      • 2.1 AbstractHandlerMethodMapping 初始化 --RequestMapping注解解析
      • 2.2 DispatcherServlet 的初始化
      • 2.3 DispatcherServlet#initHandlerMappings(...) 初始化示例说明
    • 三、工作原理

前言

本系列文章基本环境如下:

  • java8
  • springboot2.7

创建项目,使用阿里的源:https://start.aliyun.com
创建前,请先设置好自己的maven环境,java版本。保持网络正常。
在这里插入图片描述
选择spring-web的2.7.6 版本:
在这里插入图片描述在这里插入图片描述
使用阿里的源创建好项目后,会自动生成的有控制器Controller,启动类,以及一个页面。
如此,准备工作就做好了。

正文

在Java还没有SpringMvc时,使用的是servlet + jsp 的方式,对外提供接口,以及和页面进行数据交互等操作。
但是,这种操作,毕竟还是不方便,功能也不够强大。
曾经的写法,需要配置xml文件,如果页面够多,光配置就是一大堆。

发展到后来,servlet3.0的时候,出现了完全注解版的写法。

关于servlet的描述这里不做过多解释,本文将对对springmvc中使用到的servlet特征进行阐述,继而分析它的设计原理,springmvc启动原理,以及工作原理

等到在Spring框架中的时候,就已经是DispatcherServlet了。

而它本身就是一个servlet,其类关系图如下:
在这里插入图片描述

一、设计原理

1.1 servlet生命周期简述

Servlet生命周期分为三个阶段:

  1. 初始化阶段:调用init()方法实现初始化工作。
  2. 运行阶段:处理请求,容器创建代表HTTP请求的ServletRequest对象和代表HTTP响应的ServletResponse对象,并将它们作为参数传递给Servletservice()方法。
  3. 销毁阶段:Servlet将被销毁,生命周期结束。

Servlet本身只是一个接口,在HttpServlet实现类中,对service()方法进行了实现。
而这里的实现是套用了模版方法设计模式,将service的职责拆分了,按照请求方法的类型不同划分。

比如,如果请求方法是 GET请求,则会执行到 HttpServletdoGet方法;如果是POST请求,则会执行到 HttpServletdoPost方法。

FrameworkServlet 又对HttpServlet中的service方法进行了重写:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());if (httpMethod != HttpMethod.PATCH && httpMethod != null) {super.service(request, response);} else {this.processRequest(request, response);}}

这里判断了请求方法,默认执行 HttpServletservice方法。
但是实际调用的是 doGetdoPost这类方法。而同时,这类方法也被FrameworkServlet重写了

也就是说,servlet 会触发执行到 FrameworkServletprocessRequest 方法。如下图所示:在这里插入图片描述
这里会执行FrameworkServletdoService方法。而这是一个抽象方法。其子类DispatcherServlet 对其进行了实现。如此便贯通了。

1.2 设计原理小结

在1.1小节中的分析中,Servlet继承&实现的关系如下:
在这里插入图片描述
也就是说,在servlet处理请求时,对于springmvc而言,就是执行 doService方法。

二、启动原理

这一小节,主要分析SpringBoot项目启动时,对SpringMvc部分的处理。

2.1 AbstractHandlerMethodMapping 初始化 --RequestMapping注解解析

谈起SpringMvc,最先想起来的俩注解应该是 ControllerRequestMapping
而关于启动项目时,框架对这俩注解的处理,基本都体现在AbstractHandlerMethodMapping中。

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {// ...省略其他方法public void afterPropertiesSet() {this.initHandlerMethods();}
}

首先,AbstractHandlerMethodMapping是个抽象类,它的子类会放到Spring容器中。
而在它的子类 RequestMappingHandlerMapping 中,对初始化方法进行了重写,具体内容如下:

public void afterPropertiesSet() {this.config = new RequestMappingInfo.BuilderConfiguration();this.config.setTrailingSlashMatch(this.useTrailingSlashMatch());this.config.setContentNegotiationManager(this.getContentNegotiationManager());if (this.getPatternParser() != null) {this.config.setPatternParser(this.getPatternParser());Assert.isTrue(!this.useSuffixPatternMatch && !this.useRegisteredSuffixPatternMatch, "Suffix pattern matching not supported with PathPatternParser.");} else {this.config.setSuffixPatternMatch(this.useSuffixPatternMatch());this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch());this.config.setPathMatcher(this.getPathMatcher());}super.afterPropertiesSet();
}

在设置了一堆配置之后,最终调用的还是 AbstractHandlerMethodMappinginitHandlerMethods 方法。

protected void initHandlerMethods() {// 获取spring容器中的beanNameString[] var1 = this.getCandidateBeanNames();int var2 = var1.length;for(int var3 = 0; var3 < var2; ++var3) {String beanName = var1[var3];if (!beanName.startsWith("scopedTarget.")) {// 通过beanName映射出methodHandlerthis.processCandidateBean(beanName);}}// 初始化handlerMethodsthis.handlerMethodsInitialized(this.getHandlerMethods());}protected void processCandidateBean(String beanName) {Class<?> beanType = null;try {// 通过beanName获取当前的类型beanType = this.obtainApplicationContext().getType(beanName);} catch (Throwable var4) {if (this.logger.isTraceEnabled()) {this.logger.trace("Could not resolve type for bean '" + beanName + "'", var4);}}// 当前beanName对应的类定义不为空,并且带有Controller 或 RequestMapping注解时,对其进行处理if (beanType != null && this.isHandler(beanType)) {this.detectHandlerMethods(beanName);}}

可以看到,最终处理控制器时,是调用了detectHandlerMethods 方法。具体内容如下:

protected void detectHandlerMethods(Object handler) {// 通过beanName获取到对应的类型Class<?> handlerType = handler instanceof String ? this.obtainApplicationContext().getType((String)handler) : handler.getClass();if (handlerType != null) {// 获取你自己定义的控制器类型Class<?> userType = ClassUtils.getUserClass(handlerType);// 将类中符合条件(标注了RequestMapping注解)的 method 映射为 RequestMappingInfo 对象,并放入map中;这一步的实现,在其子类中。并且聚合它们的请求路径。Map<Method, T> methods = MethodIntrospector.selectMethods(userType, (method) -> {try {return this.getMappingForMethod(method, userType);} catch (Throwable var4) {throw new IllegalStateException("Invalid mapping on handler class [" + userType.getName() + "]: " + method, var4);}});// 记录日志if (this.logger.isTraceEnabled()) {this.logger.trace(this.formatMappings(userType, methods));} else if (this.mappingsLogger.isDebugEnabled()) {this.mappingsLogger.debug(this.formatMappings(userType, methods));}// 方法注册methods.forEach((method, mapping) -> {Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);this.registerHandlerMethod(handler, invocableMethod, mapping);});}}

这里对方法的处理分了两步,第一步,根据类型简单处理注解,主要是聚合了请求路径。聚合后的结果如下:

可以看到,这里的路径属性已经有值了。
然后就是注册方法了。
而真正注册的方法registerHandlerMethod 是在其子类中实现的。具体内容如下:
在这里插入图片描述

在其父级的实现中,注册的结果如下:
在这里插入图片描述

最后,简单处理RequestBody注解(如果使用了该注解,参数必填)。

2.2 DispatcherServlet 的初始化

框架中定义了自动配置类 DispatcherServletAutoConfiguration。其有个内部类 DispatcherServletConfiguration 对 DispatcherServlet 进行了配置。具体如下:

@Conditional({DefaultDispatcherServletCondition.class})
@ConditionalOnClass({ServletRegistration.class})
@EnableConfigurationProperties({WebMvcProperties.class})
protected static class DispatcherServletConfiguration {protected DispatcherServletConfiguration() {}@Bean(name = {"dispatcherServlet"})public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {DispatcherServlet dispatcherServlet = new DispatcherServlet();dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());return dispatcherServlet;}@Bean@ConditionalOnBean({MultipartResolver.class})@ConditionalOnMissingBean(name = {"multipartResolver"})public MultipartResolver multipartResolver(MultipartResolver resolver) {return resolver;}
}

在第一节设计原理的时候,提到过DispatcherServlet 也是一个servlet 。那么它的初始化,也就包含在servlet的生命周期中。

在servlet生命周期中,有 init 方法,进行初始化。FrameworkServlet 有一个父类HttpServletBean,其中定义了初始化方法。虽然不是原生的servlet 初始化方法,但是也是会间接调用到的(通过模版方法设计模式,由子类代为实现)

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware 

FrameworkServlet 触发初始化时,会执行到 initServletBean 方法。其中有两个比较关键初始化方法,具体如下:
在这里插入图片描述
篇幅原因,这里只拿出关键代码。initWebApplicationContext()内,有这样一段,在处理请求时,会执行到:

if (!this.refreshEventReceived) {synchronized(this.onRefreshMonitor) {this.onRefresh(wac);}
}

onRefresh 由子类DispatcherServlet 重写后,就成了这样:

protected void onRefresh(ApplicationContext context) {this.initStrategies(context);
}protected void initStrategies(ApplicationContext context) {// 初始化上传文件解析器initMultipartResolver(context);// 初始化本地解析器initLocaleResolver(context);// 主题处理器initThemeResolver(context);// 映射处理器initHandlerMappings(context);// 处理适配器initHandlerAdapters(context);// 异常处理器initHandlerExceptionResolvers(context);// 请求到视图名的翻译器initRequestToViewNameTranslator(context);// 视图解析器initViewResolvers(context);// 初始化FlashManagerinitFlashMapManager(context);
}

如果大家想看看这里执行的内容,以及初始化后的结果,可以自行打断点查看。这里因为东西较多,我就不截图了。

PS: 下一小节以 HandlerMappings 为例,进行说明

2.3 DispatcherServlet#initHandlerMappings(…) 初始化示例说明

private void initHandlerMappings(ApplicationContext context) {this.handlerMappings = null;if (this.detectAllHandlerMappings) {// 获取所有的handlerMappingMap<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);// 对handlerMapping进行排序if (!matchingBeans.isEmpty()) {this.handlerMappings = new ArrayList(matchingBeans.values());AnnotationAwareOrderComparator.sort(this.handlerMappings);}} else {try {// 获取名字是 handlerMapping 的handlerMappingHandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);this.handlerMappings = Collections.singletonList(hm);} catch (NoSuchBeanDefinitionException var4) {}}// handlerMappings为空,需要设置默认的handlerMappingif (this.handlerMappings == null) {this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);if (this.logger.isTraceEnabled()) {this.logger.trace("No HandlerMappings declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");}}Iterator var6 = this.handlerMappings.iterator();while(var6.hasNext()) {HandlerMapping mapping = (HandlerMapping)var6.next();if (mapping.usesPathPatterns()) {this.parseRequestPath = true;break;}}
}

默认情况下,如果配置了使用全部,会有以下handlerMapping:
在这里插入图片描述
另外补充一句,如果使用默认的handlerMapping,需要配置DispatcherServlet.properties

三、工作原理

这一小节,以DispatcherServlet 为起点,分析SpringMvc的工作原理。

// todo 待完善–预计2024春节后补充,春节期间玩去了。

http://www.dt0577.cn/news/34026.html

相关文章:

  • 所有的网站建设教程seo技术 快速网站排名
  • 多少钱要交个人所得税seo关键词推广怎么做
  • 网站后台登录代码百度指数有什么参考意义
  • 有没有给别人做图赚钱的网站汕头seo推广优化
  • 做移动网站优化优2024年新闻摘抄十条
  • wordpress 微服务seo网络营销推广公司深圳
  • 网站源码论坛海外网站推广的公司
  • 标准化信息网站建设与应用想做网络推广如何去做
  • 做网站的人 优帮云开发一个网站需要多少钱
  • 十大网红电商郑州seo排名优化公司
  • 闵行网站建设查网站是否正规
  • 广告代运营公司百度seo
  • 微网站模板 php网站查询入口
  • 网站qq聊天代码seo服务方案
  • 登录门户网站平面设计培训班学费一般多少
  • 建设网站 编程思路seo关键词排名优化
  • 英文网站模板制作北京seo关键词排名优化软件
  • 东莞常平嘉盛学校seo排名哪家正规
  • 揭阳网站建设网站天津seo标准
  • 网站建设平台流程韶关今日头条新闻
  • 网站备案提交资料1000个关键词
  • 织梦网站排版能调整吗引流推广平台
  • 萝岗区营销型网站建设网站建设的数字化和互联网化
  • 西安建设厅网站新手如何自己做网站
  • 怎样做网站的关键词seo怎么优化武汉厂商
  • ps网页排版设计网站seo排名优化价格
  • 佛山顺德做网站百度收录怎么做
  • 公司网站的seo怎么做网站平台有哪些
  • django网站开发实例源码烘焙甜点培训学校
  • 建网站商城广州seo公司