dtcms svn VMware audio vue注册组件 前端vue框架 vue请求 找公司做网站 java 数据分析 mysql修改字段值 java时间戳 axure导出html文件 linux启动mysql命令 pythonassert函数 python中len函数 python中import用法 python设置环境变量 python如何定义变量 java包 java生成文件 linux服务器 php实例代码 找茬辅助 主板排名天梯图 ps怎么插入表格 pr缩放 陌陌电脑直播设置教程 selinux关闭 机械键盘个别键位失灵 c4d挤压怎么用 游戏linux正则表达式 mp4剪切合并大师 视频添加水印 现代操作系统 oemdiy 免费ftp空间 文件压缩工具 加字幕软件 未来教育考试系统 SQLite编辑器
当前位置: 首页 > 学习教程  > 编程语言

SpringMVC详解——SpringBoot扩展SpringMVC原理和全面接管SpringMVC

2020/11/4 15:06:04 文章标签:

** 如果想在SpringBoot中扩展一些SpringMVC的配置,例如需要配置自定义的视图解析器或拦截器等,需要怎么实现呢?** 例如,自定义一个视图解析器: Configuration public class MyConfig implements WebMvcConfigurer {Ov…

** 如果想在SpringBoot中扩展一些SpringMVC的配置,例如需要配置自定义的视图解析器或拦截器等,需要怎么实现呢?**
例如,自定义一个视图解析器:

@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("index");
    }
}

我们只需要编写一个配置类去实现WebMvcConfigurer接口,并选择实现接口中的方法,不能标注@EnableWebMvc,这些WebMvcConfigurer接口中的方法就是SpringMVC所可以扩展的配置

注意:在SpringBoot1.0版本中扩展SpringMVC配置是继承WebMvcConfigurerAdapter类,但在2.0以上的版本中已经过时,官方推荐使用以上实现WebMvcConfigurer接口的方式进行扩展,因为在2.0版本中WebMvcConfigurer接口有了默认实现。

WebMvcConfigurer方法介绍:这里只列举几个比较关键的方法

public interface WebMvcConfigurer {
	//定制URL匹配规则
	default void configurePathMatch(PathMatchConfigurer configurer) {
	}
	//内容协商机制
	default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	}
	//异步任务执行器。
	default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
	}
	//使用默认servlet处理静态资源
	default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	}
	//添加格式转换器
	default void addFormatters(FormatterRegistry registry) {
	}
	//添加拦截器
	default void addInterceptors(InterceptorRegistry registry) {
	}
	//添加视图解析器
	default void addViewControllers(ViewControllerRegistry registry) {
	}
}

扩展MVC的实现原理

  • 我们都知道WebMvcAutoConfiguration是SpringMVC的自动配置类,当在做其他配置导入时,导入了@Import(EnableWebMvcConfiguration.class)这样一个注解,这个注解有什么用?
	@Configuration(proxyBeanMethods = false)
	@Import(EnableWebMvcConfiguration.class)
	@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
	@Order(0)
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
	}

  • 点进这个注解,发现他还是WebMvcAutoConfiguration里的一个静态内部类,但他继承了DelegatingWebMvcConfiguration
	@Configuration(proxyBeanMethods = false)
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
	}

  • 再点进这个DelegatingWebMvcConfiguration类里,开头有这样一段代码,有一个configurers属性,类型是WebMvcConfigurerComposite ,这个WebMvcConfigurerComposite类也实现了WebMvcConfigurer,当@Autowired标注在一个方法上说明,这个方法的参数都从容器中获取,这里是从容器中获取所有的WebMvcConfigurer,并赋值给了configurers属性
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
}

  • 在这个类往下看,发现这个类的方法跟WebMvcConfigurer接口里的方法一样,以这个视图解析器举例,方法里调用了这个方法this.configurers.addViewControllers(registry)
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}

	...

	@Override
	protected void addViewControllers(ViewControllerRegistry registry) {
		this.configurers.addViewControllers(registry);
	}
}

  • 点进configurers.addViewControllers(registry),这个方法是把容器中所有的addViewControllers()都执行一遍。因为我们自己写的配置类也注入到了容器里,所以我们的配置也会被调用,并且也被SpringBoot自动配置上,所以SpringMVC的自动配置和我们的扩展配置都会起作用
class WebMvcConfigurerComposite implements WebMvcConfigurer {
	...

	@Override
		public void addViewControllers(ViewControllerRegistry registry) {
			for (WebMvcConfigurer delegate : this.delegates) {
				delegate.addViewControllers(registry);
			}
		}
}

还有上面在写自定义配置类时为什么不能标注@EnableWebMvc

因为一但标注了@EnableWebMvc,所有都是我们自己配置;所有的SpringMVC的自动配置都失效了。原理又是怎么样的?

给自己的配置类加上@EnableWebMvc

@Configuration
@EnableWebMvc
public class myConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("index");
    }
}

这个注解导入了@Import(DelegatingWebMvcConfiguration.class)

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

这个类继承了WebMvcConfigurationSupport

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
}

我们再回头看一下WebMvcAutoConfiguration,@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)这个注解的意思就是容器中没有这个组件的时候,这个自动配置类才生效

秃头乐园欢迎你 解锁更多的干货暗号:CSDN

小结:大概了解到SpringBoot扩展SpringMVC的原理和全面接管SpringMVC,但SpringBoot中还有其他很多配置,只要了解其中的原理,其他配置也就一通百通了。
以上就是就是本篇文章的所有内容啦,感谢看到最后的朋友,都看到最后了,点个赞再走啊,如有对之处还请多多指正。


本文链接: http://www.dtmao.cc/news_show_350325.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?