【SpringMVC】SpringMVC简介、过程分析、bean的加载和控制

news2025/1/17 3:52:04

文章目录

  • 1. SpringMVC简介
  • 2. SpringMVC入门案例
    • 文件结构
    • 第一步:坐标导入
    • 第二步:创建SpringMVC容器的控制器类
    • 第三步:初始化SpringMVC环境,设定Spring加载对应的bean
    • 第四步:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术请求的处理
    • 测试
    • 总结:使用到的一些注解及入门程序开发总结
  • 3. 入门案例工作流程分析
    • 启动服务器初始化过程
    • 单次请求过程
  • 4. bean的加载与控制
    • 方式一:
    • 方式二:
    • 将Spring下的bean也加载到Servlet容器中
    • 小结

1. SpringMVC简介

在这里插入图片描述
数据层框架: MyBatis
表现层框架: Servlet->SpringMVC (即SpringMVC属于一种表现层框架)
简介: SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
优点:

  • 使用简单,开发便捷(相比于Servlet)
  • 灵活性强

2. SpringMVC入门案例

文件结构

在这里插入图片描述

第一步:坐标导入

pom.xml文件中添加一些依赖,这些依赖版本之间是相互联系的,如果配错或配太低都不行

<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>springmvc_01_test</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-api</artifactId>
      <version>10.1.7</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

第二步:创建SpringMVC容器的控制器类

控制器类来指定对应的访问网址什么的,@Controller标明这是一个bean,@RequestMapping指定访问路径,@ResponseBody指定返回不做任何解析和处理

package com.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("User save...");
        return "{'module': 'springmvc'}";
    }
}

第三步:初始化SpringMVC环境,设定Spring加载对应的bean

类似于Spring的配置,通过@Configuration指定为配置类,通过@ComponentScan来指定扫描的控制器范围

package com.demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.demo.controller")
public class SpringMvcConfig {
}

第四步:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术请求的处理

这里相当于是一些固定的写法

package com.demo.config;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {
//    加载SpringMVC容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
//    设置哪些请求归属SpringMVC处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
//    加载Spring配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

测试

配置Run Configurations
在这里插入图片描述
然后启动,在浏览器里输入http://localhost/save可看到结果:
在这里插入图片描述

总结:使用到的一些注解及入门程序开发总结

@Controller:类注解,放在SpringMVC控制器上方,作用是设定SpringMVC的核心控制器bean
@RequestMapping:方法注解,放在SpringMVC控制器方法定义上方,作用是设置当前控制器方法的请求路径
@ResponseBody:方法注解, 放在SpringMVC控制器方法定义上方,作用是设置当前控制器方法相应内容为当前返回值,无需解析
在这里插入图片描述

3. 入门案例工作流程分析

启动服务器初始化过程

  1. 服务器启动,执行ServletContainerInitConfig类,初始化Web容器
  2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
  3. 加载SpringMVCConfig
  4. 执行@ComponentScan对应的bean
  5. 加载UserController(也就是加载扫描包下注释了@Controller的那些类),每个@RequestMapping的名称都对应一个具体的方法(注意:如图中/save->save()的映射实际上并不是放在每一个bean中管理的,而是由SpringMVC放在统一的地方进行管理的)
  6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC
    在这里插入图片描述

单次请求过程

  1. 发送请求localhost/save
  2. web容器发现所有的请求都经过SpringMVC(上面的6,定义了所有的请求都经过SpringMVC),将请求交给SpringMVC处理
  3. 解析请求路径/save
  4. /save匹配执行对应的方法save()
  5. 执行save()
  6. 检测到有@ResponseBody,直接将save()方法的返回值作为响应请求体返回给请求方

4. bean的加载与控制

SpringMVC相关的bean是表现层的bean:

  • SpringMVC加载的bean对应的包均在com.xx.controller包内

Spring控制的bean:

  • 业务bean(Service)
  • 功能bean(DataSource等)
  • 方式一:Spring加载的bean设定扫描范围为com.xx,排除掉controller包内的bean
  • 方式二:Spring加载的bean设定扫描范围为精准范围,例如service, dao包等
  • 方式三:不区分Spring和SpringMVC的环境,加载到同一个环境中

方式一:

指定大的扫描类型,在其中通过excludeFilters排除掉一些东西,具体写法如下,我们需要再excludeFilters里边指定清楚过滤的规则

package com.demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(value = "com.demo",
        excludeFilters = @ComponentScan.Filter(
            type = FilterType.ANNOTATION,
            classes = Controller.class
        )
)
public class SpringConfig {
}

执行一下测试,看能否再拿到注释了@ControllerUserController类(注意,在测试之前要注释掉SpringMvcConfig上的@Configuration):

package com.demo;

import com.demo.config.SpringConfig;
import com.demo.controller.UserController;
import com.demo.domain.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserController userController = ctx.getBean(UserController.class);
        System.out.println(userController);
    }
}

执行测试代码会报错:
在这里插入图片描述
如果取消掉这个过滤规则,再执行测试代码会发现不会报错,而是会打印拿到的实例信息。通过测试说明使用excludeFilters这种方法是可以过滤包的
解释一下为什么要注释掉SpringMvcConfig上的@Configuration:因为我们在SpringConfig中扫描了com.demo下的所有包,在SpringMvcConfig上我们使用@Configuration注解了它是一个配置类,那么这个配置就会被扫描,它所包括的所有bean也会被加载进来,如果将SpringMvcConfig放到com.demo下而不注释也可以解决这个问题(老师在视频里是这么讲的,但是我自己试了一下好像把SpringMvcConfig放到com.demo下,不注释也会被加载进来,不知道是不是我的问题)

方式二:

我们使用mybatis技术来进行开发,这里的com.demo.dao是可以不写的,因为mybatis通过自动代理的技术可以扫到com.demo.dao下的bean(在Mybatis的MapperScannerConfigurer中有设置msc.setPackage("...")
但是假如我们使用JDBC的技术来进行开发,我们就必须扫描com.demo.dao下的包,否则我们就没有数据层的bean,Spring下JDBC的开发可以看一下这篇文章:Spring jdbc数据库管理,所以对于com.demo.dao的扫描还是建议写,这样通用性比较好,如果不写的话通用性就会比较差

package com.demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"com.demo.service", "com.demo.dao"})
public class SpringConfig {
}

将Spring下的bean也加载到Servlet容器中

修改ServletContainersInitConfig类中的内容,加上加载Spring配置的内容:

package com.demo.config;

import com.demo.controller.SpringConfig;
import com.demo.controller.SpringMvcConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {
//    加载SpringMVC容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
//    设置哪些请求归属SpringMVC处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
//    加载Spring配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
}

在Servlet容器中加载SpringMVC和Spring配置还有一个简化的类及写法,以下是以上的简化开发:

package com.demo.config;

import com.demo.controller.SpringConfig;
import com.demo.controller.SpringMvcConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

小结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯技术工程总结-如何写好技术文章?

文章参考&#xff1a;腾讯技术工程《写好一篇高质量的技术文章》 如何写好技术文章&#xff1f; 大家可以先思考一下&#xff0c;为什么要写技术文章&#xff1f; 我们写技术文章的目的是什么呢&#xff1f;面向哪些人呢&#xff1f; 面向人群 写技术文章的目的毫无疑问是为…

linux应急响应基础和常用命令

linux应急响应 linux应急响应基础和常用命令基于linux系统本身进行应急响应。 系统基础信息获取 获取linux服务器基本信息 命令&#xff1a; uname -a内存cpu信息 cat /proc/cpuinfo cat /proc/meminfo lscpu free -m lsmod #查看载入的模块信息进程查看 动态进程查看 …

PDF如何转换制作成翻页电子书

很多朋友想将PDF转换制作成一本翻页电子书&#xff0c;却不知道如何操作。其实&#xff0c;转换翻页电子书的过程并不难&#xff0c;只需要掌握一些基本的技巧和方法就可以了。 基本该怎么操作呢&#xff1f; 1.首先需要一个工具帮助我们成功转换&#xff0c;推荐使用FLBOOK这…

系统架构设计师教程(七)系统架构设计基础知识

系统架构设计基础知识 7.1 软件架构概念7.1.1 软件架构的定义7.1.2 软件架构设计与生命周期需求分析阶段设计阶段实现阶段构件组装阶段部署阶段后开发阶段 7.1.3 软件架构的重要性 7.2 基于架构的软件开发方法7.2.1 体系结构的设计方法概述7.2.2 概念与术语7.2.3 基于体系结构的…

【二分查找】自写二分函数的总结

作者推荐 【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数 本文涉及的基础知识点 二分查找算法合集 自写二分函数 的封装 我暂时只发现两种&#xff1a; 一&#xff0c;在左闭右开的区间寻找最后一个符合条件的元素&#xff0c;我封装成FindEnd函数。…

Automotive Bionics

汽车仿生学是一种通过模拟生物系统的某些特征来设计汽车的方法。一些典型的汽车仿生学例子包括&#xff1a; 鲨鱼式车型&#xff1a;这种车型的设计灵感来源于鲨鱼的流线型身体&#xff0c;这种设计能够减少空气阻力和水阻力&#xff0c;提高车辆的燃油效率和行驶速度。 甲壳虫…

JavaSE第7篇:封装

文章目录 一、封装1、好处:2、使用 二、四种权限修饰符三、构造器1、作用2、说明3、属性赋值的过程 一、封装 封装就是将类的属性私有化,提供公有的方法访问私有属性 不对外暴露打的私有的方法 单例模式 1、好处: 1.只能通过规定的方法来访问数据 2.隐藏类的实例细节,方便…

HarmonyOS云开发基础认证考试满分答案(100分)【全网最全-不断更新】【鸿蒙专栏-29】

系列文章&#xff1a; HarmonyOS应用开发者基础认证满分答案&#xff08;100分&#xff09; HarmonyOS应用开发者基础认证【闯关习题 满分答案】 HarmonyOS应用开发者高级认证满分答案&#xff08;100分&#xff09; HarmonyOS云开发基础认证满分答案&#xff08;100分&#xf…

DC-4靶场

目录 nmap进行主机发现 尝试反弹shell&#xff1a; 进入交互式shell&#xff1a; Hydra爆破jim用户密码&#xff1a; ssh登录charles &#xff1a; 提权&#xff08;三种方法&#xff09;&#xff1a; exim4提权…

数据高可用架构设计与实现

大型企业如何实现 MySQL 到 Redis 的同步 前面曾提到过 Read/Write Through 和 Cache Aside 这几种更新缓存的模式或者说策略&#xff0c;这几种策略都存在缓存不命中的可能性&#xff0c;如果缓存没有命中&#xff0c;就需要直接访问数据库以获取数据。—般情况下&#xff0c…

Ansible-playbook编译.yml脚本

1、playbook是什么&#xff1f; 在Ansible中&#xff0c;Playbook是用于配置、部署和管理被控节点的剧本。它由一个或多个play&#xff08;角色&#xff09;组成&#xff0c;每个play可以包含多个task&#xff08;台词&#xff0c;动作&#xff09;。使用Ansible的Playbook&am…

【Windows】windows11右键默认显示更多选项的办法

Windows11系统的右键菜单显示&#xff0c;需要多点一次“显示更多选项”才能看到所有菜单内容&#xff0c;按下面步骤简单设置一下就能恢复成Windows经典的右键菜单显示。 1. 2.输入命令【reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a…

JMESPath语言

JMESPath&#xff08;JSON Matching Expression Path&#xff09; 一种查询语言。 主要用于从JSON文档中检索和过滤数据。 通过写表达式提取和处理JSON数据&#xff0c;而无需编写复杂的代码。 功能&#xff1a;数据提取、过滤、转换、排序。 场景&#xff1a;处理API响应…

中文编程工具下载,编程工具构件之复选框构件

一、前言 零基础自学编程&#xff0c;中文编程工具下载&#xff0c;中文编程工具构件之扩展系统菜单构件教程 编程系统化教程链接https://jywxz.blog.csdn.net/article/details/134073098?spm1001.2014.3001.5502 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&a…

【案例】--“特别抢购”案例

目录 一、案例背景二、技术方案思路三、技术方案具体设计3.1、表设计3.2、Java代码实现一、案例背景 A公司向供应商B公司买了一套软件产品。B公司的这套产品有多个应用系统服务【如appId1、appId2、appId3】,每个应用都有各自的业务应用场景,但都需要管理文档,那么就需要磁…

C++:函数重载

1.函数重载概念 函数重载就是用同一个函数名定义的不同函数&#xff0c;当函数名和不同的参数搭配时函数的功能和含义不同。 2.实现函数重载的条件 同一个作用域&#xff0c;参数个数不同或者参数类型不同或者参数顺序不同(满足一个即可) void func(){} void func(int x){} v…

74hc244驱动数码管显示电路及程序

把七或八只发光二极管组合在一个模件上组成了个8字和小数点&#xff0c;用以显示数字。为了减少管脚&#xff0c;把各个发光管的其中同一个极接在一起作为共用点&#xff0c;因此就产生了共阳极和共阴极数码之说。共阳管就是把各个发光管的正极接在一起&#xff0c;而共阴管就刚…

web(HTML之表单练习)

使用HTML实现该界面&#xff1a; 要求如下&#xff1a; 用户名为文本框&#xff0c;名称为 UserName&#xff0c;长度为 15&#xff0c;最大字符数为 20。 密码为密码框&#xff0c;名称为 UserPass&#xff0c;长度为 15&#xff0c;最大字符数为 20。 性别为两个单选按钮&a…

PowerShell实战(一)PowerShell使用ImportExcel模块轻松操作Excel

目录 一、介绍 二、安装模块 三、操作示例 1、导出excel 2、读取Excel数据 3、导出包含图表的Excel 4、导出包含汇总列和图表的Excel 一、介绍 ImportExcel模块可以理解为基于PowerShell环境操作Excel的强大类库&#xff0c;使用它可以在 Windows、Linux 和 Mac 上都可以使用。…

天选姬·桌宠 你值得拥有

天选姬桌宠 简介官网地址安装教程1.获取方式2.安装3.功能效果4.桌宠互动5.下载地址 彩蛋搜狗输入法天选姬主题天选姬桌宠视频简介天选姬静态壁纸天选姬动态壁纸 天选姬桌宠 简介 互动类虚拟桌面宠物&#xff0c;让你的桌面变得有趣和精彩。 官网地址 载中心 | 官方支持 | A…