Spring Boot | SpringBoot对 “SpringMVC“的 “整合支持“、SpringMVC“功能拓展实现“

目录:

    • [SpringMVC 的 "整合支持" ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发")](#SpringMVC 的 “整合支持” ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发"))
      • [1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些"自动配置",自动把相关的类加入到IOC容器中 )](#1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些“自动配置”,自动把相关的类加入到IOC容器中 ))
      • [2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些"功能拓展" )](#2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些”功能拓展“ ))
        • [2.1 项目基础环境搭建](#2.1 项目基础环境搭建)
        • [2.2 功能拓展实现 ( MVC拓展功能 ):](#2.2 功能拓展实现 ( MVC拓展功能 ):)
          • [① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" )](#① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" ))
          • [② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加"拦截器",默认情况下,SpringBoot不会自动为项目配置一个"拦截器" )](#② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加“拦截器”,默认情况下,SpringBoot不会自动为项目配置一个“拦截器” ))

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材 为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著

文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。

欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


  • 通常在 Web 开发中,会涉及 静态资源的** 访问支持** 、视图解析器配置转换器格式化器定制文件上传下载 等功能,甚至还需要考虑 到与Web服务器关联Servlet相关组件定制
  • Spring Boot框架 支持整合一些 常用Web框架 ,从而实现Web开发 ,并 默认支持Web开发中的一些** 通用功能**。

SpringMVC 的 "整合支持" ( 引入"Web依赖启动器",几乎可以在无任何额外的配置的情况下进行"Web开发")

  • 为了在SpringBoot实现并简化Web开发SpringBoot 为一些**常用的Web开发框架**提供了 整合支持,例如 Spring MVCSpring WebFlux 等框架 ,使用 SpringBoot进行Web开发 时,只需要在 项目引入 对应 Web开发框架依赖启动器 即可。

1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后,SpringBoot会自动进行一些"自动配置",自动把相关的类加入到IOC容器中 )

  • Spring Boot项目 中,一旦引入Web依赖启动器 : spring-boot-starter-web ,那么SpringBoot 整合Spring MVC框架

    默认实现的一些 xxxAutoConfiguration 自动配置类 就会** 自动生效** ( 通过配置类相关的类 加入到IOC容器 中 ) ,几乎 可以在无任何额外配置 的情况下 进行Web 开发

  • SpringBoot为整合** SpringMVC框架 实现Web开发** ,主要提供了以下 自动化配置功能特性

    (1)内置两个视图解析器 : ContentNegotiatingViewResolverBeanNameViewResolver

    (2) 支持静态资源以及 WebJars
    (3)自动注册了** 转换器 格式化器** 。

    (4)支持 Http消息转换器

    (5)自动注册 了**消息代码解析器**。
    (6)支持静态项目首页 index.html
    (7)支持** 定制应用图标 favicon.ico**。
    (8)自动** 初始化** Web数据绑定器ConfigurableWebBindingInitializer

  • Spring Boot 整合Spring MVC 进行 Web开发 时 提供了很多默认配置,而且 大多数时候 使用 默认配置可满足开发需求

    例如,Spring Boot整合Spring MVC 进行Web开发 时,不需要额外配置视图解析器

2.Spring MVC功能扩展实现 ( 实际开发中,SpringBoot提供了很多自动化配置,但还要进行一些"功能拓展" )

  • 导入web场景依赖启动器后Spring Boot会为MVC开发 进行很多"自动化配置 ",但在 实际开发中 还需要进行关于MVC开发功能拓展 ,下面将通过一个具体的案例讲解Spring Boot整合Spring MVC框架 中的 MVC功能拓展
    对一些 功能进行扩展实现
2.1 项目基础环境搭建
  • 基础环境搭建


    MyLocalResolver.java :

    java 复制代码
    package com.myh.chapter_10.config;
    
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.servlet.LocaleResolver;
    import org.thymeleaf.util.StringUtils;
    
    import java.util.Locale;
    
    @Configuration
    public class MyLocalResolver implements LocaleResolver {
        @Override
        public Locale resolveLocale(HttpServletRequest httpServletRequest) {
            String l = httpServletRequest.getParameter("l");
            String header = httpServletRequest.getHeader("Accept-Language");
            Locale locale = null;
            if (!StringUtils.isEmpty(l)) {
                String[] split = l.split("_");//根据-进行字符串拆分
                locale = new Locale(split[0], split[1]);
            } else {
                String[] splits = header.split(",");
                String[] split = splits[0].split("-");
                locale = new Locale(split[0], split[1]);
            }
            return locale;
        }
    
        @Override
        public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    
        }
    
        @Bean //将该方法的返回值对象交给IOC容器管理
        public LocaleResolver localeResolver() {
            return new MyLocalResolver();
        }
    }

    LoginController.java :

    java 复制代码
    package com.myh.chapter_10.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    import java.util.Calendar;
    
    @Controller
    public class LoginController {
    
        @GetMapping("/toLoginPage")
        public String toLoginPage(Model model) { //参数类型为Model类型,该类型可以返回文本给前端
            model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
            return "login"; //String的返回值类型可以返回一个视图
        }
    }

    login.properties :

    properties 复制代码
    login.tip=请登录
    login.username=用户名
    login.password=密码
    login.rememberme=记住我
    login.button=登录

    login_en_US.properties :

    properties 复制代码
    login.tip=Please sign in
    login.username=Username
    login.password=Password
    login.rememberme=Remember me
    login.button=Login

    login_zh_CN.properties :

    properties 复制代码
    login.tip=请登录
    login.username=用户名
    login.password=密码
    login.rememberme=记住我
    login.button=登录

    css 和 img ( 百度网盘 )


    login.html :

    html 复制代码
    <!DOCTYPE html>
    <!-- 让该页面支持 -->
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
        <title>用户登录页面</title>
        <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
        <link th:href="@{/login/css/signin.css}" rel="stylesheet">
    </head>
    <body class="text-center">
    <form class="form-signin">
        <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72"/>
        <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">请登录</h1>
        <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
        <input type="password" class="form-control" th:placeholder="#{login.password}" required="">
        <div class="checkbox mb-3">
            <label> <input type="checkbox" value="remember-me"/>[[#{login.rememberme}]]</label>
        </div>
        <button class="btn btn-lg btn-primary btn-block" type="submit" th:test="#{login.button}">登录</button>
        <p class="mt-5 mb-3 text-muted">@<span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p>
        <a class="btn btn-sm" th:href="@{/toLoginPage(l='zh_CN')}">中文</a>
        <a class="btn btn-sm" th:href="@{/toLoginPage(l='en_US')}">English</a>
    </form>
    </body>
    </html>

    pom.xml :

    xml 复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>3.2.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.myh</groupId>
        <artifactId>chapter_10</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>chapter_10</name>
        <description>chapter_10</description>
        <properties>
            <java.version>17</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    <!--    <build>-->
    <!--        <plugins>-->
    <!--            <plugin>-->
    <!--                <groupId>org.springframework.boot</groupId>-->
    <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
    <!--            </plugin>-->
    <!--        </plugins>-->
    <!--    </build>-->
    
    </project>

    运行项目后 ,访问 http://localhost:8080/toLoginPage 能查看到项目的登录页面login.html如下所示

2.2 功能拓展实现 ( MVC拓展功能 ):
  • SpringBoot提供 了很多关于 MVC 的 "自动化配置 ",很多 MVC对象默认配置好 / 大部分MVC内容SpringBoot 都给你 自动默认配置 好了,很多的 MVC功能 / MVC效果都是可以** 免配置直接使用的 ( 如: 实现的页面跳转 ) ,但此时 如果想要使用** 一些 拓展功能 / 实现功能的拓展 :可以通过 WebMvcConfigurer 这个 接口来实现,WebMvcConfigurer 接口 有很多 方法 ,** 该接口** 中的 方法 可用于 "MVC功能拓展"

    • "MVC功能拓展功能① " : 注册 "视图管理器" :

      视图管理器 " 可以 将"多个url"自动映射指定 的"视图页面 "上 , 通过 WebMvcConfigurer接口addViewController( ViewControllerRegistry registry )方法 即可创建"视图管理器" ,达到想要的需求效果。

    • "MVC功能拓展功能② " :自定义 "拦截器 " :

      自定义一个拦截器 ( 用于拦截url请求 ) ,在SpringBoot的MVC 中用这个 自定义的 "拦截器" 替代 SpringBoot中 "默认的拦截器"

    • "MVC功能拓展功能③ " :注册 "格式化器" :

    • ... ( 其他MVC拓展功能 )

      ( WebMvcConfigurer接口 中的每一个方法可用于拓展MVC功能 )

① 创建"视图管理器" ( 属于MVC拓展功能,要自行在SpringBoot进行"相关配置" )
  • "视图管理器" 能解决的需求 : 可以 将"多个url"自动映射指定 的"视图页面 "上 ,例如 : 通过配置"视图管理器 " 可以让 /toLoginPage请求/login.html请求 都"自动映射 "到login.html 这个页面中。

  • 创建 视图管理器操作步骤/流程为 :

    首先 创建一个** 类实现WebMvcConfigurer接口**
    中重写该 接口addViewController( ViewControllerRegistry registry**)方法** 。
    方法体 中通过ViewControllerRegistry对象 中的 setViewName( )方法来** 决定哪些url能访问指定的" 视图页面**"。

  • 视图管理器例子如

    在"项目基础环境搭建"代码基础上添加如下代码

    MyMVCconfig.java :

    java 复制代码
    package com.myh.chapter_10.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * 在SpringBoot中提供了很多关于MNC的"自动化配置",很多MVC对象都默认配置好/大部分MVC内容SpringBoot都给你自动默认配置好了,很多的
     * MNC功能/MVC效果都是可以免配置直接使用的(如:实现的页面跳转),但此时如果想要使用一些拓展功能/实现功能的拓展:可以通过
     * WebMvcConfigurer这个接口来实现,WebMvcConfigurer接口有很多方法,该接口中的方法可用于"MVc功能拓展。
     *
     *     MVC拓展功能① : 视图管理器 :
     *     现在你想要实现无论用户访问/toLoginPage 还是 访问/login.html 还是其他ulr 都能跳转到 login.html这个页面,这时候就可以调用
     *     WebMvcConfigurer接口 的 addViewControllers(ViewControllerRegistry registry) 方法来来创建"视图管理器"的方式来实现"上面要求的效果"
     *     ( 通过"视图管理器"可以实现多个url访问到同一个"视图页面",但通过这种方式是无法在后端中传递"参数"给"视图页面的",这时可用拓展功能中的  "过滤器": 来赋值/传递之给"指定的视图页面" )
     *
     */
    @Configuration //比较给类为"配置类",同时将给类加入到IOC容器中
    public class MyMVCconfig implements WebMvcConfigurer { //该类实现了用于MVC功能拓展的"WebMvcConfigurer接口"
    
        /**
         * SpringBoot中的关于MVC的拓展功能一 : 视图管理器
         *   具体的操作为:
         *   ①首先创建一个类实现WebMvcConfigurer接口(改接口的作用: 通过该接口中的方法来拓展MVC功能)
         *   ②在类中重写WebMvc中关于能实现"视图管理器"效果的addViewController(ViewControllerRegistry registry)方法
         *   ③在方法体中通过ViewControllerRegistry对象中的方法来决定哪些url能访问指定的"视图页面"
         */
        //添加"视图管理器" (属于SpringBoot中的MVC的"拓展功能")
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            //让 /toLoginPage 这个请求自动映射到 login.html这个页面中
            registry.addViewController("/toLoginPage222").setViewName("login");
    
            //让 /login.html 这个请求自动映射到 login.html这个页面
            registry.addViewController("/login222.html").setViewName("login");
        }
    }

    MyMVCconfig 实现了接口 WebMvcConfigureraddViewControllers ( ViewControllerRegistry registry ) 方法。在** addViewControllers( )方法内部** ,使用ViewControllerRegistryaddViewControlle( )方法 分别定义了 /toLoginPage222/login222.htm 的请求控制,并使用setViewName ("login ')方法 将路径映射为** login.html页面** 。定制完MVC视图管理器功能后,就可以进行效果测试了,项目启动成功后,在浏览器上分别访问http://localhost:8080/toLoginPage222http://localhost:8080/login222.html 效果如下图所示 :

    从上图的运行效果可以看出,使用 WebMvConfigurer接口定义的** 用户请求控制方法也实现了 用户请求控制跳转效果** ,相比于传统的请求处理方法而言 ,这种方法 更加简洁直观和** 方便** 。同时也可以看出,使用这种方式无法获取后台处理的数据例如登录页面中的年份。

    需要说明的是,使用WebMveConfigurer接口 中的addViewControllers(ViewControllerRegistry registry)方法定制视图控制只适合较为简单无参数视图Get方式请求跳转,对于 有参数 或需要 业务处理的** 跳转需求** , 最好还是采用传统方式处理请求


    注意点 :

    使用"视图管理器 "的方式来通过多url路径访问 到"指定视图页面 " , 有 如上图所示的 问题 ,这时可用 MVC拓展功能 中的 : 创建拦截器 ,在拦截器 中给"指定视图 "传递数据

② 创建"自定义拦截器" ( 将该 "自定义的拦截器" 用于在SpringBoot的MVC开发中添加"拦截器",默认情况下,SpringBoot不会自动为项目配置一个"拦截器" )
  • 注册自定义拦截器WebMvcConfigurer接口提供了许多** MVC开发相关方法** ,例如,添加 "拦截器" 方法 addInterceptors( )方法添加 "格式化器" 方法 addFormatters( ) 等。

  • 注册自定义拦截器 代码例子如 :

    项目基础环境搭建 代码的基础上 添加如下代码

    MyInterceptor.java : ( 自定义的"拦截器")

    java 复制代码
    package com.myh.chapter_10.config;
    
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.util.Calendar;
    
    /**
      自定义的拦截器,用于替代SpringBoot中MVC的默认的"拦截器" ,可通过实现HandlerInterceptor接口来自定义一个拦截器 :
      用于拦截"指定的请求" 和 对"指定的请求"放行
     */
    @Component //将该类加入到IOC容器中
    public class MyInterceptor implements HandlerInterceptor { //实现HandlerInterceptor接口
    
        /**
         * preHandle : 预处理方法 :
         * url请求发出后,先执行"拦截器"中的preHandle()方法,再执行controller中的方法
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            /**
             *   request.getRequestURI() : 获取并返回"发送请求"的客户端请求的 "URI字符串"。
             *
             *   URI(统一资源标识符) : uri为url的一部分,但不包括协议和 主机名(域名或IP地址)
             *   例如,如果请求的完整 URL 是 http://www.example.com/some/info.html 那么 request.getRequestURI()方法
             *   将返回 /some/info.html
             *    ---上面的内容即为uri(统一资源标识符)
             */
            String uri = request.getRequestURI(); //获得请求中的"统一资源标识符/uri"
            Object loginUser = request.getSession().getAttribute("LoginUser");//如果已登录,会在session中的添加一个LoginUser属性
            /*
               用户请求/admin开头路径时,判断用户是否登录
             */
            //判断uri是否以/admin开头
            if (uri.startsWith("/admin") && null == loginUser) {
                //进入这里面表明用户还未登录,拦截器将不对该url放行,同时重定向到login.html页面(同时跳转到login.html页面)
                response.sendRedirect("/toLoginPage");
                return false;
            }
            //没进if语句中,表明其要么不是/admin请求开头,要么是没登录的用户,对其放行
            return true;
        }
    
        /**
         * postHandle : 	该方法会在执行"控制器方法"之后执行,但在"渲染视图页面"之前执行。可以通过此方法对请求域中的"模型和视图"做出进一步的修改
         * url请求发出后,先执行"拦截器"中的preHandle()方法,再执行controller中的方法,然后就是执行postHandle()方法, 然后就是"渲染视图页面",最后执行afterCompletion()方法
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            //想request域中存放当前年份用于"前端页面"动态展示
            request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
        }
        
        /**
         * afterCompletion : 该方法在 "整个请求完成" 后执行,即"视图渲染"结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等。
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        }
        
         //接下来将该自定义的"拦截器"添加到SpringBoot中,通过WebMvcConfigurer接口中的 addInterceptors()方法为将该拦截器加入到SpringBoot中 }

    WebMvcConfigurer.java : ( 自定义的"拦截器")

    java 复制代码
    package com.myh.chapter_10.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    
    /**
     * 在SpringBoot中提供了很多关于MNC的"自动化配置",很多MVC对象都默认配置好/大部分MVC内容SpringBoot都给你自动默认配置好了,很多的
     * MNC功能/MVC效果都是可以免配置直接使用的(如:实现的页面跳转),但此时如果想要使用一些拓展功能/实现功能的拓展:可以通过
     * WebMvcConfigurer这个接口来实现,WebMvcConfigurer接口有很多方法,该接口中的方法可用于"MVc功能拓展。
     *
     *     MVC拓展功能 (其中之一) : 自定义"拦截器"
     */
    @Configuration //比较给类为"配置类",同时将给类加入到IOC容器中
    public class MyMVCconfig implements WebMvcConfigurer { //该类实现了用于MVC功能拓展的"WebMvcConfigurer接口"
    
    
    
    
        /**
         * 使用 addInterceptors(InterceptorRegistry registry) 方法将"自定义拦截器" 加入到 SpringBoot中
         */
        @Autowired
        private MyInterceptor myInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            /*
              addPathPatterns() : 要拦截的url路径
              excludePathPatterns() : 不进行拦截的url路径
             */
            registry.addInterceptor(myInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns("/login.html");
        }
    }

项目启动成功后,在浏览器上分别访问http://localhost:8080/admin 自动跳转 到了 用户登录页面 ,同时在 页面中动态显示 出了 当前年份 ,这就说明了定制 的"自定义拦截器 " 生效


  • 需要说明的是Spring Boot整合Spring MVC 过程中提供了许多默认自动化配置特性 ,开发者可以通过Spring Boot 提供的 WebMvcConfigurer接口MVC功能 进行 定制和扩展

    如果开发者不想使用Spring Boot整合MVC 时提供的一些 默认配置 ,而是想要 绝对自定义管理 ,那么可以编写 一个 @Configuration注解配置类 ,同时添加 @EnableWebMvc注解 来 关闭Spring Boot提供所有关于MVC功能的** 默认配置**。

相关推荐
用户685453759776932 分钟前
同步成本换并行度:多线程、协程、分片、MapReduce 怎么选才不踩坑
后端
javaTodo40 分钟前
Claude Code 记忆机制详解:从 CLAUDE.md 到 Auto Memory,六层体系全拆解
后端
LSTM971 小时前
使用 C# 和 Spire.PDF 从 HTML 模板生成 PDF 的实用指南
后端
JaguarJack1 小时前
为什么 PHP 闭包要加 static?
后端·php·服务端
BingoGo1 小时前
为什么 PHP 闭包要加 static?
后端
是糖糖啊2 小时前
OpenClaw 从零到一实战指南(飞书接入)
前端·人工智能·后端
百度Geek说2 小时前
基于Spark的配置化离线反作弊系统
后端
后端AI实验室2 小时前
用AI写代码,我差点把漏洞发上线:血泪总结的10个教训
java·ai
Java编程爱好者2 小时前
虚拟线程深度解析:轻量并发编程的未来趋势
后端