SpringMVC的全注解开发

2023-10-26

一、spring-mvc.xml 中组件转化为注解形式

跟之前全注解开发思路一致, xml配置文件使用核心配置类替代,xml中的标签使用对应的注解替代

<!-- 组件扫描web层 -->
<context:component-scan base-package="com.itheima.controller"/>

<!--注解驱动-->
<mvc:annotation-driven/>

<!--配置文件上传解析器-->
<bean id="multipartResolver" 
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

<!--配置拦截器-->
<mvc:interceptors>
	<mvc:interceptor>
		<mvc:mapping path="/*"/>
		<bean class="com.itheima.interceptor.MyInterceptor01"></bean>
	</mvc:interceptor>
</mvc:interceptors>

<!--配置DefaultServletHttpRequestHandler-->
<mvc:default-servlet-handler/>

⚫ 组件扫描,可以通过@ComponentScan注解完成;
⚫ 文件上传解析器multipartResolver可以通过非自定义Bean的注解配置方式,即@Bean注解完成

@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMVCConfig {
	@Bean
	public CommonsMultipartResolver multipartResolver() {
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setDefaultEncoding("UTF-8");
		multipartResolver.setMaxUploadSize(3145728);
		multipartResolver.setMaxUploadSizePerFile(1048576);
		multipartResolver.setMaxInMemorySize(1048576);
		return multipartResolver;
	}
}

< mvc:annotation-driven>、< mvc:default-servlet-handler /> 和 < mvc:interceptor > 怎么办呢?SpringMVC 提供了一个注解@EnableWebMvc,我们看一下源码,内部通过@Import 导入了DelegatingWebMvcConfiguration类

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {}
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
	// 从容器中注入WebMvcConfigurer类型的Bean
	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
	//省略其他代码
}

WebMvcConfigurer类型的Bean会被注入进来,然后被自动调用,所以可以实现WebMvcConfigurer接口,完成一些解析器、默认Servlet等的指定,WebMvcConfigurer接口定义如下:

public interface WebMvcConfigurer {
	// 配置默认Servet处理器
	default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { }
	
	// 添加拦截器
	default void addInterceptors(InterceptorRegistry registry) { }
	
	// 添加资源处理器
	default void addResourceHandlers(ResourceHandlerRegistry registry) { }
	
	// 添加视图控制器
	default void addViewControllers(ViewControllerRegistry registry) { }
	
	// 配置视图解析器
	default void configureViewResolvers(ViewResolverRegistry registry) { }
	
	// 添加参数解析器
	default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { }
	
	// ... 省略其他代码 ...
}

创建MyWebMvcConfigurer实现WebMvcConfigurer接口,实现addInterceptors 和 configureDefaultServletHandling方法

@Component
public class MyWebMvcConfigurer implements WebMvcConfigurer {
	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		// 开启DefaultServlet,可以处理静态资源了
		configurer.enable();
	}
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 创建拦截器对象,进行注册
		// Interceptor的执行顺序也取决于添加顺序
		registry.addInterceptor(new MyInterceptor01()).addPathPatterns("/*");
	}
}

最后,在SpringMVC核心配置类上添加@EnableWebMvc注解

@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMVCConfig {
	@Bean
	public CommonsMultipartResolver multipartResolver(){
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setDefaultEncoding("UTF-8");
		multipartResolver.setMaxUploadSize(3145728);
		multipartResolver.setMaxUploadSizePerFile(1048576);
		multipartResolver.setMaxInMemorySize(1048576);
		return multipartResolver;
	}
}

二、DispatcherServlet加载核心配置类

DispatcherServlet在进行SpringMVC配置文件加载时,使用的是以下方式:

<!--配置springMVC前端控制器-->
<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!--指定springMVC配置文件位置-->
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-mvc.xml</param-value>
	</init-param>
	<!--服务器启动就创建-->
	<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

现在是使用SpringMVCConfig核心配置类替代的spring-mvc.xml,怎么加载呢?参照Spring的ContextLoaderListener加载核心配置类的做法,定义了一个AnnotationConfigWebApplicationContext,通过代码注册核心配置类

public class MyAnnotationConfigWebApplicationContext extends AnnotationConfigWebApplicationContext {
	public MyAnnotationConfigWebApplicationContext() {
	// 注册核心配置类
	super.register(SpringMVCConfig.class);
	}
}
<!--指定springMVC的applicationContext全限定名 -->
<init-param>
	<param-name>contextClass</param-name>
	<param-value>com.itheima.config.MyAnnotationConfigWebApplicationContext</param-value>
</init-param>

三、消除web.xml

目前,几乎消除了配置文件,但是web工程的入口还是使用的web.xml进行配置的,如下:

<!--配置springMVC前端控制器-->
<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!--指定springMVC的applicationContext全限定名 -->
	<init-param>
		<param-name>contextClass</param-name>
		<param-value>com.itheima.config.MyAnnotationConfigWebApplicationContext</param-value>
	</init-param>
	<!--服务器启动就创建-->
	<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

⚫ Servlet3.0环境中,web容器提供了javax.servlet.ServletContainerInitializer接口,实现了该接口后,在对应的类加载路径的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作;
⚫ 基于这个特性,Spring就定义了一个SpringServletContainerInitializer实现了ServletContainerInitializer接口;
⚫ 而SpringServletContainerInitializer会查找实现了WebApplicationInitializer的类,Spring又提供了一个WebApplicationInitializer的基础实现类AbstractAnnotationConfigDispatcherServletInitializer,当我们编写类继承AbstractAnnotationConfigDispatcherServletInitializer时,容器就会自动发现我们自己的类,在该类中我们就可以配置Spring和SpringMVC的入口了。

按照下面的配置就可以完全省略web.xml

public class MyAnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	// 返回的带有@Configuration注解的类用来配置ContextLoaderListener
	protected Class<?>[] getRootConfigClasses() {
		System.out.println("加载核心配置类创建ContextLoaderListener");
		return new Class[]{ApplicationContextConfig.class};
	}
	
	// 返回的带有@Configuration注解的类用来配置DispatcherServlet
	protected Class<?>[] getServletConfigClasses() {
		System.out.println("加载核心配置类创建DispatcherServlet");
		return new Class[]{SpringMVCConfig.class};
	}
	
	// 将一个或多个路径映射到DispatcherServlet上
	protected String[] getServletMappings() {
		return new String[]{"/"};
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC的全注解开发 的相关文章

  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • Hibernate 的 PersistentSet 不使用 hashCode/equals 的自定义实现

    所以我有一本实体书 public class Book private String id private String name private String description private Image coverImage pr
  • Spring 3 匹配通配符严格,但找不到元素 'jee:jndi-lookup' 的声明

    所以我遇到了与这里类似的问题 Spring 3 0错误 匹配通配符严格 但找不到元素的声明 https stackoverflow com questions 8651781 spring 3 0 error the matching wi
  • Java ResultSet 如何检查是否有结果

    结果集 http java sun com j2se 1 4 2 docs api java sql ResultSet html没有 hasNext 方法 我想检查 resultSet 是否有任何值 这是正确的方法吗 if resultS
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp

随机推荐

  • MySQL-binlog2sql:非主从关系实现数据的【数据同步+数据恢复+数据追踪】

    文章目录 MySQL binlog2sql 非主从实时同步 恢复误删数据 1 引 1 介绍 2 功能 3 针对3种场景 4 脚本汇总说明 2 先决条件 1 安装 MySQL 2 修改 MySQL 配置 3 安装 binlog2sql 1 解
  • yii2 mysql设置时区

    第一步 修改配置文件 common config db php 注 8 00为北京时间 Asia Shanghai common config main php 第二步 修改vendor yiisoft yii2 db Connection
  • 抓取网站中的视频

    最近想从别人家的网站宣传片上提取一些素材 借鉴一下 之前也没有弄过 但是我的思路就是从网页的缓存中查找播放完后缓存的视频 然后失败了 然后又想到了网页打开源代码 然后查找到网页源代码饮用的视频的路径 然后找到视频 然后 再次失败 网上找了好
  • css基础———清除浮动的一些方法及区别

    为什么要清楚浮动 地址 http blog csdn net qwe502763576 article details 78811658 清除浮动方法概览 这里例举四种常见的清除浮动方式 方式一 使用overflow属性来清除浮动 ovh
  • 论文阅读

    简介 paper https arxiv org abs 1911 11907 github https github com huawei noah ghostnet Ghostnet CVPR2020 是华为提出的一种轻量级网络 结构类
  • WSL安装

    WSL安装教程 WSL简介 Windows Subsystem for Linux 简称WSL 是一个在Windows10上能够运行原生Linux二进制可执行文件 ELF格式 的兼容层 它是有微软与Canonical公司合作开发 其目标正是
  • 模糊查询与带参数跳转

    一 模糊查询 使用
  • 方法重写(override)原则

    方法的重写 override 两同两小一大原则 1 方法名相同 参数类型相同 2 子类返回类型小于等于父类方法返回类型 3 子类抛出异常小于等于父类方法抛出异常 4 子类访问权限大于等于父类方法访问权限
  • oracle RAC ORA-03113 错误解决

    好久 没有更新博客 太懒了 这咋换工作呢 1 错误现象 数据库 客户端连接不正常 频繁报 ORA 03113 错误 oracle 文档中对这个错误这样解释 ORA 03113 错误就是说连接到数据库的网络中断了 有些错误由于频繁出现 原因复
  • res_company_white_url.py 详解

    res company white url py 主要作用是 在数据库中建立一个表 存放白名单的URL 当我们读取文件时 先判断Referer是否在白名单中 如果不在则自动转到一个图片文件 防止盗链 接下来我们看一下主要代码 class C
  • unexpected keyword argument 'renderer'-DjangoUeditor

    今天在集成DjangoUeditor按照官方的Github集成之后 本以为就可以看到后台了没想到直接报错 render got an unexpected keyword argument renderer 报错93行 boundfield
  • 【QT】——06_带参数的信号(笔记)

    信号重载 说明 信号是可以重载的 相同的名字不同的参数 在发射信号的时候给值 emit musicSignal 100 音乐菜单 主窗口 h 创建一个带参的槽来处理信号 注意槽的参数要与信号一致 void dealMusic2 int QS
  • 《Hadoop学习笔记系列》二.Hadoop分布式文件系统 HDFS

    0 Hadoop分布式文件系统 HDFS HDFS以流式数据访问模式来存储超大文件 运行与商用硬件集群上 1 流式数据访问 HDFS的构建思路 一次写入 多次读取是最高效的访问模式 2 Block数据块 HDFS基本读写单位 类似于磁盘的页
  • STM32的ADC采样与多通道ADC采样

    一 单通道采样 参考资料 STM32库开发实战指南 刘火良 杨森著 原理性质的东西还是少讲 因为上面那本书里面讲解的很详细了 直接来看硬件电路图 这里使用的是3362电位器 10K 即用STM32来测量PB0和GND两端的电压 这样的电路设
  • 一篇明白SQL的执行顺序

    这是一条标准的查询语句 这是我们实际上SQL执行顺序 我们先执行from join来确定表之间的连接关系 得到初步的数据 where对数据进行普通的初步的筛选 group by 分组 各组分别执行having中的普通筛选或者聚合函数筛选 然
  • 小谈HashMap与ConcurrentHashMap

    HashMap JDK7 在JDK7中 HashMap通过数组加链表的形式存储 当元素个数达到阈值 并且数组下标已经存在元素 则会进行扩容 如果数组下标不存在元素 则直接添加 不会扩容 JDK7中添加元素使用的是头插法 在高并发的环境下可能
  • [算法通关村] 1.3 链表的删除

    上一节我们谈到了链表的头插 尾插 中间插入的方法 忘记的小伙伴可以复习一下 算法通关村 1 2 链表的插入 接下来 完成链表的删除工作 我们在上一节的学习中 分别在链表的开头 中间和结尾插入了节点 现在我们想使链表恢复原来的样子 即 1 g
  • 更多的服务商从业者都开始关注刷脸支付

    刷脸支付就是通过人脸进行支付 简单来说消费者在接入蜻蜓的商家结账付款时 只需将脸面对蜻蜓上的摄像头即可完成支付 在这一过程中用户甚至不需要用手机 支付效率相比扫码支付更加的高效 此外由于支付宝刷脸支付是基于3D人脸识别技术 在安全也要比扫码
  • 【机器学习】编码、创造和筛选特征

    在机器学习和数据科学领域中 特征工程是提取 转换和选择原始数据以创建更具信息价值的特征的过程 假设拿到一份数据集之后 如何逐步完成特征工程呢 文章目录 一 特性类型分析 1 1 数值型特征 1 2 类别型特征 1 3 时间型特征 1 4 文
  • SpringMVC的全注解开发

    文章目录 一 spring mvc xml 中组件转化为注解形式 二 DispatcherServlet加载核心配置类 三 消除web xml 一 spring mvc xml 中组件转化为注解形式 跟之前全注解开发思路一致 xml配置文件