springboot webmvc初始化:一个登陆异常引出的话题
1.场景复现:
一个登陆异常引出的问题。
我们通过精心组织组件扫描的方式,来装配不同的子模块,形成一个可运行的应用;
在载入某个子模块后,我们发现应用虽然正常启动,但尝试登陆的时候,出现一个很异常的异常,部分stacktrace如下:
processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.mobile.device.Device] with root cause java.lang.NoSuchMethodException: org.springframework.mobile.device.Device.<init>() |
异常栈部分调用关系如下:

如果移除子模块,应用启动后,同一个入口会触发的正常调用栈如下:

换句话说,异常情况和正常情况,走了不同的处理链。
1.我们初步怀疑是包冲突,但验证后排除掉这个问题;
2.然后继续通过调试代码,分析发现加入子模块后,启动的
HandlerMethodArgumentResolver 实例有27个;
而不加入子模块,启动的
HandlerMethodArgumentResolver 实例有33个,多了几个resolver,其中包括DeviceHandlerMethodArgumentResolver,看起来找到好的线索了;
3.根据线索,怀疑是配置问题,首先怀疑的是安全方面的配置问题;但一直测试分析没有得到结果;
4.后续,用排除法,发现此模块中去掉一个定义的配置类,问题就可以得到解决,这个配置如下::
Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
...
}
2.经过所有线索的梳理,这个问题产生的内在机制比较明确了:
HandlerMethodArgumentResolver
源码注释:
Strategy interface for resolving method parameters into argument values in the context of a given request.
简单可以理解为:解析方法参数的策略接口;通俗的理解为,(controller的)参数解析(构造)转换按这个接口来实现;
WebMvcConfigurationSupport
源码注释:
This is the main class providing the configuration behind the MVC Java config.
其中有一个方法:
@Bean |
简而言之,DeviceHandlerMethodArgumentResolver 实例是靠
WebMvcConfigurationSupport 提供的机制(模板函数),加载进容器处理链的;
DelegatingWebMvcConfiguration
实际上,spring 依靠
DelegatingWebMvcConfiguration 自动检测并代理实现所有的自定义配置
/**
* A subclass of {@code WebMvcConfigurationSupport} that detects and delegates
* to all beans of type {@link WebMvcConfigurer} allowing them to customize the
* configuration provided by {@code WebMvcConfigurationSupport}. This is the
* class actually imported by {@link EnableWebMvc @EnableWebMvc}.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
WebMvcAutoConfiguration
DelegatingWebMvcConfiguration 的实例创建,是通过下面这个类
WebMvcAutoConfiguration 导入,但是有个条件:当容器内不存在 WebMvcConfigurationSupport 的实例时
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
所以,当我们自己子模块的代码,有这个自定义配置时
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
系统默认的webmvc 配置行为将会被覆盖;
springboot webmvc初始化:一个登陆异常引出的话题的更多相关文章
- 基于SpringBoot如何实现一个点赞功能?
基于SpringBoot如何实现一个点赞功能? 解析: 基于 SpringCloud, 用户发起点赞.取消点赞后先存入 Redis 中,再每隔两小时从 Redis 读取点赞数据写入数据库中做持久化存储 ...
- ZeroMQ接口函数之 :zmq_msg_init - 初始化一个空的ZMQ消息结构
ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq_msg_init zmq_msg_init(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...
- ZeroMQ接口函数之 :zmq_msg_init_data - 从一个指定的存储空间中初始化一个ZMQ消息对象的数据
ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq_msg_init_data zmq_msg_init_data(3) ØMQ Manual - ØMQ/3.2.5 ...
- [Android]ViewPager如何只初始化一个页面
使用过ViewPager的应该都知道,ViewPager的setoffscreenpagelimit()方法,使用该方法可以设置在ViewPager滑动时,左右两侧各保存多少个页面,那我们直接设置se ...
- 如何初始化一个iOS原生地图
/** 初始化一个mapView 需导入 #import <MapKit/MapKit.h> - returns: 返回一个mapView对象 */ mapView = [[MKMapV ...
- 标准程序员系列-Github篇-初始化一个代码仓库
下面将一步步介绍怎样使用GitHub来初始化一个项目的版本控制仓库: 1. 到GitHub上注册自己的账号:https://github.com/ 2. 创建第一个代码仓库一个仓库相当于一个项目的代码 ...
- @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationEx ...
- 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ----初始化一个线程
使用线程的一个常见问题就是如何能够在一个线程开始运行之前,适当地将它初始化.初始化最常见的理由就是为了调整优先权.另一个理由是为了在SMP 系统中设定线程比较喜欢的 CPU.第10 章谈到 MFC 时 ...
- tkinter如何设置界面消失 当制作一个登陆界面时,登陆成功之后,如何让登陆界面本身消失
tkinter如何设置界面消失 当制作一个登陆界面时,登陆成功之后,如何让登陆界面本身消失 if querySQL.checkAll():#用户名和密码都输入正确 self.root.withdraw ...
随机推荐
- 深入理解 Java 多线程核心知识
多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲.在平时工作中如若使用不当会出现数据错乱.执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关 ...
- 面试官问我“Java中的锁有哪些?以及区别”,我跪了
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...
- mysql批量更新数据
CREATE PROCEDURE `sp_update_temp_data`( out po_returnvalue ) ) leave_top:BEGIN #Routine body goes he ...
- SpringBoot Tomcat启动报错
中间的桥梁就是下面这个依赖 <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over ...
- windows下共享文件夹在Linux下打开
①首先在Windows下创建一个准备用来共享用的文件夹 ②在虚拟机下选择第一步创建的文件夹为共享文件夹 ③在虚拟机shell命令框下输入 cd /mnt/sgfs 回车进入共享文件夹. 备注:其他细 ...
- BTrace:线上问题排查工具
BTrace简介 GitHub地址:BTrace 下载地址:v1.3.11.3 官方使用教程:Btrace使用教程 使用场景 BTrace 是一个事后工具,所谓事后工具就是在服务已经上线了,但是发现存 ...
- PTA编程总结2—币值转换
7-1 币值转换 (20 分) 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式.如23108元,转换后变成"贰万叁仟壹百零捌"元.为了简 ...
- jquery.validator 手机号验证
1.在input中加上mobile="true",maxlength="11" <label class="w170 control-label ...
- hp quicktestprofession ver-10.0(QTP)的入门使用指南
---恢复内容开始--- SQA(software quality assurance) tool hp quicktestprofession ver-10.0(QTP) environment w ...
- python on sql
USE [DemoDb]GOexecute sp_execute_external_script @language = N'Python', @script = N'a = 1b = 2c = a/ ...