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 ...
随机推荐
- 51nod1268 和为K的组合(DFS)
1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K.如果可以 ...
- 2、每日复习点--ConcurrentHashMap vs HashMap vs HashTable
HashMap:允许键或者值为null.底层是基于数组+链表的结构.默认初始容量是16,默认加载因子是0.75F,默认扩容增加一倍.如果指定了初始容量n,n必然在(2x,2x+1]范围内,n经过运算所 ...
- 泛型集合List的详细用法
命名空间: System.Collections.Generic List<T>类是 ArrayList 类的泛型等效类. 该类使用大小可 按需动态增加 的数组实现 IList& ...
- FIT2096 Assignment 2 2019
FIT2096 Assignment 2 2019_v1.2.docx 9/04/2019 11:34 AMPage 1 | 4FIT2096 Assignment 2 2019Transformat ...
- java开发工具STS的下载及安装
将下载后的压缩文件解压,在解压后的sts-bundle下的sts-3.9.1RELEASE目录中STS.exe便是可执行程序,用于启动STS,将该文件发送到桌面快捷方式,当我们想使用STS时可以快速的 ...
- cv2.getRotationMatrix2D函数
- 【新特性】JDK1.6
一.Desktop类和SystemTray类 在JDK6中 ,AWT新增加了两个类:Desktop和SystemTray. 前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定 ...
- Win10下JDK下载与环境变量配置
一.JDK下载 1.JDK下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...
- WebPack命令执行的时候,其内部处理逻辑是什么
1.首先webpack发现并没有通过命令的形式,给它指定入口和出口 2.向根目录查找“webpack.config.js”配置文件 3.解析这个配置文件,并得到配置文件中导出的配置对象 4.当拿到配置 ...
- 解决ubuntu无法使用root用户启动Google Chrome浏览器
1.找到Chrome的路径 # whereis google-chrome google-chrome: /usr/bin/google-chrome /usr/share/man/man1/goog ...