SpringMVC请求流程源码解析

目录
  • 一、SpringMVC使用
    • 1.工程创建
    • 2.工程配置
    • 3.启动工程
  • 二、SpringMVC启动过程
    • 1.父容器启动过程
    • 2.子容器启动过程(SpringMvc容器)
    • 3.九大组件的初始化
    • 1.处理器映射器的初始化
    • 2.处理器适配器的初始化
    • 4.拦截器的初始化
  • 三、SpringMVC请求过程
    • 1.请求流程图
    • 2.业务描述

一、SpringMVC使用

1.工程创建

  • 创建maven工程。
  • 添加java、resources目录。
  • 引入Spring-webmvc 依赖。
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.4</version>
</dependency>
  • 删除 src/main/webapp/WEB-INF/web.xml 配置文件。从tomcat的示例工程中找一份web.xml替换,这里推荐从\webapps\ROOT\WEB-INF中拿,并且在其中添加context的监听器和servlet配置,配置如下。
<!--Context 加载监听器 -->
<listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
     <servlet-name>dispatcherServlet</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
     	 <param-name>contextConfigLocation</param-name>
         <param-value>classpath:application.xml</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>
  • 在 resources 目录中创建springmvc.xml文件,并添加如下配置:
<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--配置spring包扫描路径,被@Component、@Controller、@Service、@Repository标注的类都会交由Spring托管一个Bean-->
    <context:component-scan base-package="com.ybe.*"/>
    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
  • 在 src/main/webapp/WEB-INF/下添加 applicationContext.xml文件,配置如下:
<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
  • 创建Controller类,代码如下:
package com.ybe.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String helloWorld(){
        System.out.println("hello world");
        return "index";
    }
}

2.工程配置

  • 点击Add Configurations或者Run->Add Configurations。

配置本地tomcat的目录

配置浏览器地址,点击上图左上角的 + 号,选择Tomcat Server选项后,点击 Deployment 选项,点击 右边的 + 号。

选择Artifacts后,选择springMvcTest:war。

3.启动工程

二、SpringMVC启动过程

​ SpringMVC是依赖Java的Web容器技术,整个springmvc的启动过程是建立在Servlet技术基础上的。SpringMVC借助Web容器和Servelt的生命周期进行了扩展。父容器的初始化在 ContextLoaderListener 类中initWebApplicationContext方法进行,子容器的初始化在 DispatcherServlet 中init方法中进行。

1.父容器启动过程

​ 如果web.xml中配置了ContextLoaderListener监听器,则web容器启动的时候先会调用监听器ContextLoaderListener的initWebApplicationContext方法。整个过程如下图:

​ initWebApplicationContext中的整个过程就是创建了一个spring容器(父容器),并且根据springApplication.xml的配置内容往Spring容器中注入Bean对象。最后把spring容器(this.context对象)放入serveltContext 的属性中。

2.子容器启动过程(SpringMvc容器)

​ DispatcherServlet 是在web.xml配置文件中配置的Servlet类,是SpringMVC的请求分发核心类。所有的请求都由DispatcherServlet去分发处理。

​ DispatcherServlet 的继承关系如下图:

​ 上图可知DispatcherServlet 继承了HttpServletBean。在HttpServletBean中重写了init(),Web容器启动的时候会根据配置文件中定义的Servlet进行创建,并且会根据配置项(load-on-startup)觉定在什么时候调用Servlet的init方法,init方法在整个Servlet的生命周期中只会调用一次。初始化init方法的主体实现过程如下:

1.WebApplicationContextUtils.getWebApplicationContext(getServletContext()) 从ServletContext中获取属性为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的对象,即Spring父容器对象。

2.wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener())),给子容器添加应用监听器,该监听器在后面的finishRefresh()方法中进行触发,方法里面封装了初始化SpringMVC中九大组件的逻辑。

3.publishEvent(new ContextRefreshedEvent(this))发布Context刷新事件,会触发SourceFilteringListener监听器,最终进行initStrategies的调用。

3.九大组件的初始化

initStrategies是SpringMVC中九大组件的初始化方法其中9个方法对应9个组件的初始化,本文中只讲映射器和适配器的创建过程,initStrategies代码如下:

// 初始化 MultipartResolver:主要用来处理文件上传.如果定义过当前类型的bean对象,那么直接获取,如果没有的话,可以为null
initMultipartResolver(context);
// 初始化 LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver),基于session的配置(SessionLocaleResolver),基于cookie的配置(CookieLocaleResolver)
initLocaleResolver(context);
// 初始化 ThemeResolver:主要用来设置主题Theme
initThemeResolver(context);
// 初始化 HandlerMapping:映射器,用来将对应的request跟controller进行对应
initHandlerMappings(context);
// 初始化 HandlerAdapter:处理适配器,主要包含Http请求处理器适配器,简单控制器处理器适配器,注解方法处理器适配器
initHandlerAdapters(context);
// 初始化 HandlerExceptionResolver:基于HandlerExceptionResolver接口的异常处理
initHandlerExceptionResolvers(context);
// 初始化 RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或逻辑视图名称,并且在该方法中没有直接往response的输出流里面写数据的时候,spring将会采用约定好的方式提供一个逻辑视图名称
initRequestToViewNameTranslator(context);
// 初始化 ViewResolver: 将ModelAndView选择合适的视图进行渲染的处理器
initViewResolvers(context);
// 初始化 FlashMapManager: 提供请求存储属性,可供其他请求使用
initFlashMapManager(context);

1.处理器映射器的初始化

1.initHandlerMappings 初始化映射器,在此方法中第一步会获取容器中实现了HandlerMapping的Bean对象,如果有则用自定义的HandlerMapping实现类作为this.handlerMappings的值;如果没有自定义类,则获取SpringMVC预先定义好的策略类。代码流程如下:

2.ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);获取DispatcherServlet.properties资源文件,位置在spring-webmvc中,路径resources/org/springframework/web/servlet/DispatcherServlet.properties,该资源文件中定义了SpringMVC组件的默认实现策略类,具体内容如下:

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,org.springframework.web.servlet.function.support.HandlerFunctionAdapter
    org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

​ 由内容可知HandlerMapping 预制的策略类有 BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping,其中 RequestMappingHandlerMapping 是我们常用的 HandlerMapping对象。

3.RequestMappingHandlerMapping 的初始化,因为RequestMappingHandlerMapping 实现了InitializingBean接口,所以在容器中初始化完之后会执行afterPropertiesSet方法,其中会调用super.afterPropertiesSet();父类为AbstractHandlerMethodMapping。此方法中会调用initHandlerMethods(),代码如下:

protected void initHandlerMethods() {
    // 遍历 Bean ,逐个处理
    for (String beanName : getCandidateBeanNames()) {
        // 排除目标代理类,AOP 相关,可查看注释
        if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
            // 处理 Bean
            processCandidateBean(beanName);
        }
    }
    // 初始化处理器的方法们,目前没有特殊业务逻辑,只是打印日志
    handlerMethodsInitialized(getHandlerMethods());
}

4.processCandidateBean方法中会判断BeanName的Bean是否有Controller.class或者RequestMapping.class注解来生成具体的HandlerMethod对象。

2.处理器适配器的初始化

1.initHandlerAdapters 适配器初始化,过程和映射器相似。从上面的内容可知HandlerAdapter与之的策略类有 HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter、HandlerFunctionAdapter。其中 RequestMappingHandlerAdapter 是我们常用的处理器适配器。

2.RequestMappingHandlerAdapter实现了InitializingBean接口,在容器中初始化完之后会调用afterPropertiesSet方法,在此方法中会初始化参数解析器、绑定参数解析器、返回值解析器。此方法代码如下:

@Override
public void afterPropertiesSet() {
    // Do this first, it may add ResponseBody advice beans
    // 初始化注释了@ControllerAdvice的类的相关属性
    initControllerAdviceCache();

    // 初始化 argumentResolvers 属性
    if (this.argumentResolvers == null) {
        List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
        this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
    }
    // 初始化 initBinderArgumentResolvers 属性
    if (this.initBinderArgumentResolvers == null) {
        List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
        this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
    }
    // 初始化 returnValueHandlers 属性
    if (this.returnValueHandlers == null) {
        List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
        this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
    }
}

4.拦截器的初始化

因为所有的HandlerMapping预制的策略类都继承了AbstractHandlerMapping ,而AbstractHandlerMapping 实现了ApplicationContextAware接口,所以在具体的HandlerMapping策略类初始化完之后会调用initApplicationContext方法,该方法中具体实现了拦截器的创建,代码如下:

protected void initApplicationContext() throws BeansException {
    // 空实现,交给子类实现,用于注册自定义的拦截器到interceptors中,目前暂无子类实现
    extendInterceptors(this.interceptors);
    // 扫描已注册的MappedInterceptor的Bean们,添加到adaptedInterceptors中
    detectMappedInterceptors(this.adaptedInterceptors);
    // 将interceptors初始化成 HandlerInterceptor类型,添加到adaptedInterceptors中
    initInterceptors();
}

三、SpringMVC请求过程

1.请求流程图

2.业务描述

1.请求进来后会调用FrameworkServlet的service()方法,该方法中会调用(HttpServlet) super.service 方法,其中会调用doXXX()方法,而doXXX()方法在FrameworkServlet重写,每个doXXX()方法中又会调用processRequest(request, response)方法,processRequest中会调用doService(),doService()中又会调用doDispatch(),整个业务处理逻辑定义在doDispatch方法中。

2.循环遍历在启动过程中创建的handlerMapping处理器映射器集合查找对应处理器,传入参数为 request 请求对象,返回的是HandlerExecutionChain类型的对象,代码如下

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        //遍历
        for (HandlerMapping mapping : this.handlerMappings) {
            HandlerExecutionChain handler = mapping.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
    }
    return null;
}

在getHandler方法中如果找到具体的handler对象(HandlerMethod类型),会继续封装handler对象为一个executionChain处理器链链对象(HandlerExecutionChain类型),代码如下:

Object handler = getHandlerInternal(request);
if (handler == null) {
	handler = getDefaultHandler();
}
// 如果handler为null 即返回null。说明当前的处理器映射器不匹配。
if (handler == null) {
	return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
    String handlerName = (String) handler;
    handler = obtainApplicationContext().getBean(handlerName);
}

// Ensure presence of cached lookupPath for interceptors and others
if (!ServletRequestPathUtils.hasCachedPath(request)) {
	initLookupPath(request);
}
//创建处理器链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

getHandlerInternal是多态方法,具体的实现类中有不同的实现方式。查找具体的HandlerMethod逻辑比较复杂,请自行查看源码。

3.循环遍历在启动过程中创建的handlerAdapters处理器适配器集合查找对应处理器适配器,传入参数为handler处理器对象,返回的是RequestMappingHandlerAdapter类型的处理器适配器,代码如下:

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    if (this.handlerAdapters != null) {
        //循环判断哪个适配器能处理传入的处理器
        for (HandlerAdapter adapter : this.handlerAdapters) {
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
    }
    throw new ServletException("No adapter for handler [" + handler +
                               "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

4.循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器preHandle方法。

5.处理器适配器调用处理方法,最终会执行ServletInvocableHandlerMethod.invokeAndHandle()方法,此方法中会调用invokeForRequest,invokeForRequest中会先拿到Controller中方法的具体参数值,再执行该方法,最后会返回ModelAndView对象。

6.循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器postHandle方法。

7.processDispatchResult方法中会先查找找到具体的视图引擎,代码如下:

protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
                               Locale locale, HttpServletRequest request) throws Exception {
    if (this.viewResolvers != null) {
        for (ViewResolver viewResolver : this.viewResolvers) {
            View view = viewResolver.resolveViewName(viewName, locale);
            if (view != null) {
                return view;
            }
        }
    }
    return null;
}

​ 然后渲染视图内容,底层其实就是请求的转发,代码如下:

public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
                   HttpServletResponse response) throws Exception {
    if (logger.isDebugEnabled()) {
        logger.debug("View " + formatViewName() +
                     ", model " + (model != null ? model : Collections.emptyMap()) +
                     (this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes));
    }
    //合并返回结果,将 Model 中的静态数据和请求中的动态数据进行合并
    Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
    prepareResponse(request, response);
    //进行渲染
    renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}

8.循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器afterCompletion方法。

到此这篇关于SpringMVC请求流程源码分析的文章就介绍到这了,更多相关SpringMVC请求内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于SpringMVC请求域对象的数据共享问题

    SpringMVC支持路径中的占位符. 可以通过路径的方式来传参.restful风格.使用{}做占位符在路径中指定参数,使用@PathVariable注解在参数列表中指定. <a th:href="@{/test/1}">传了参数</a> @RequestMapping("/test/{id}") public String test(@PathVariable("id")Integer id){ System.out.p

  • springmvc path请求映射到bean 方法的流程

    一.加载注册流程 1.在dispatch-servlet.xml中配置< mvc:annotation-driven/>,在控制器的方法上加入@RequestMapping注解即可. 2.mvc:annotation-driven的解析流程 会调用到自定义元素解析器的AnnotationDrivenBeanDefinitionParser.parse方法. 3.org.springframework.web.servlet.mvc.method.annotation.RequestMappin

  • SpringMVC获取请求参数笔记整理

    目录 前言 一.使用ServletAPI获取参数 二.通过控制器方法的形参获取请求参数 三.@RequestParam 四.@RequestHeader 五.@CookieValue 六.通过实体类的形参获取参数 前言 本篇文章目的是为了学习.记录和分享博主在学习 Spring MVC过程中的笔记.同时也希望本篇文章能够帮助屏幕前的你! 一.使用ServletAPI获取参数 通过 HttpServletRequest 当作形参,此时 HttpServletRequest 类型的参数表示封装了当前

  • 浅谈SpringMVC请求映射handler源码解读

    请求映射源码 首先看一张请求完整流转图(这里感谢博客园上这位大神的图,博客地址我忘记了): 前台发送给后台的访问请求是如何找到对应的控制器映射并执行后续的后台操作呢,其核心为DispatcherServlet.java与HandlerMapper.在spring boot初始化的时候,将会加载所有的请求与对应的处理器映射为HandlerMapper组件.我们可以在springMVC的自动配置类中找到对应的Bean. @Bean @Primary @Override public RequestM

  • SpringMvc接受请求参数的几种情况演示

    说明: 通常get请求获取的参数是在url后面,而post请求获取的是请求体当中的参数.因此两者在请求方式上会有所不同. 1.直接将接受的参数写在controller对应方法的形参当中(适用于get提交方式) /** * 1.直接把表单的参数写在Controller相应的方法的形参中 * * @param username * @param password * @return */ @GetMapping("/addUser1") public String addUser1(Str

  • SpringMVC请求流程源码解析

    目录 一.SpringMVC使用 1.工程创建 2.工程配置 3.启动工程 二.SpringMVC启动过程 1.父容器启动过程 2.子容器启动过程(SpringMvc容器) 3.九大组件的初始化 1.处理器映射器的初始化 2.处理器适配器的初始化 4.拦截器的初始化 三.SpringMVC请求过程 1.请求流程图 2.业务描述 一.SpringMVC使用 1.工程创建 创建maven工程. 添加java.resources目录. 引入Spring-webmvc 依赖. <dependency>

  • Kubernetes kubectl中Pod创建流程源码解析

    目录 确立目标 先写一个Pod的Yaml 部署Pod 查询Pod kubectl create 的调用逻辑 Main Match Command Create RunCreate Summary 确立目标 从创建pod的全流程入手,了解各组件的工作内容,组件主要包括以下 kubectl kube-apiserver kube-scheduler kube-controller kubelet 理解各个组件之间的相互协作,目前是kubectl 先写一个Pod的Yaml apiVersion: v1

  • Dubbo3的Spring适配原理与初始化流程源码解析

    目录 引言 Spring Context Initialization FactoryBean BeanDefinition 初始化bean 解决依赖 解决属性 Dubbo Spring的一些问题及解决办法 Dubbo spring 2.7 初始化过程 Dubbo spring 3的初始化过程 属性占位符解决失败 ReferenceBean被过早初始化问题 Reference注解可能出现@Autowire注入失败的问题 引言 Dubbo 国内影响力最大的开源框架之一,非常适合构建大规模微服务集群

  • Spring Transaction事务实现流程源码解析

    目录 一.基于xml形式开启Transaction 1. 创建数据库user 2. 创建一个maven 项目 3. 通过xml形式配置事务 1) 创建Spring命名空间 2) 开启事务配置 3) 创建UserService类 4. 测试事务 1) 抛出RuntimeException 2) 注释掉RuntimeException 二.事务开启入口TxNamespaceHandler AnnotationDrivenBeanDefinitionParser 三.AOP驱动事务 Transacti

  • SpringBoot应用启动流程源码解析

    前言 Springboot应用在启动的时候分为两步:首先生成 SpringApplication 对象 ,运行 SpringApplication 的 run 方法,下面一一看一下每一步具体都干了什么 public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args);

  • Redisson延迟队列执行流程源码解析

    目录 引言 demo示例 SUBSCRIBE指令 zrangebyscore和zrange指令 BLPOP指令 最后定时器源码解析 总结: 引言 在实际分布式项目中延迟任务一般不会使用JDK自带的延迟队列,因为它是基于JVM内存存储,没有持久化操作,所以当服务重启后就会丢失任务. 在项目中可以使用MQ死信队列或redisson延迟队列进行处理延迟任务,本篇文章将讲述redisson延迟队列的使用demo和其执行源码. demo示例 通过脚手架创建一个简易springboot项目,引入rediss

  • RocketMQ之NameServer架构设计及启动关闭流程源码分析

    目录 NameServer 1.架构设计 2.核心类与配置 NamesrvController NamesrvConfig NettyServerConfig RouteInfoManager 3.启动与关闭流程 3.1.步骤一 3.2.步骤二 3.3.步骤三 NameServer 1.架构设计 消息中间件的设计思路一般都是基于主题订阅与发布的机制,RocketMQ也不例外.RocketMQ中,消息生产者(Producer)发送某主题的消息到消息服务器,消息服务器对消息进行持久化存储,而消息消费

  • 浅析Spring Security登录验证流程源码

    一.登录认证基于过滤器链 Spring Security的登录验证流程核心就是过滤器链.当一个请求到达时按照过滤器链的顺序依次进行处理,通过所有过滤器链的验证,就可以访问API接口了. SpringSecurity提供了多种登录认证的方式,由多种Filter过滤器来实现,比如: BasicAuthenticationFilter实现的是HttpBasic模式的登录认证 UsernamePasswordAuthenticationFilter实现用户名密码的登录认证 RememberMeAuthe

  • SpringSecurity 默认表单登录页展示流程源码

    SpringSecurity 默认表单登录页展示流程源码 本篇主要讲解 SpringSecurity提供的默认表单登录页 它是如何展示的的流程, 涉及 1.FilterSecurityInterceptor, 2.ExceptionTranslationFilc,xmccmc,ter , 3.DefaultLoginPageGeneratingFilter 过滤器, 并且简单介绍了 AccessDecisionManager 投票机制  1.准备工作(体验SpringSecurity默认表单认证

  • 详解Android布局加载流程源码

    一.首先看布局层次 看这么几张图 我们会发现DecorView里面包裹的内容可能会随着不同的情况而变化,但是在Decor之前的层次关系都是固定的.即Activity包裹PhoneWindow,PhoneWindow包裹DecorView.接下来我们首先看一下三者分别是如何创建的. 二.Activity是如何创建的 首先看到入口类ActivityThread的performLaunchActivity方法: private Activity performLaunchActivity(Activi

随机推荐