在上一篇文章“”中我总结了通过XML配置文件注入的两种方式,分别是构造方法注入和set方法注入在使用set方法注入时,遇到了一个报错找了好长时间才找到问题。这个錯误是在启动服务时报出来的
现在分别贴出代码和报错信息。
spring注解报错配置文件的相关代码如下:
启动服务时的报错信息如下:
在排查報错原因的前期里我一直先入为主的认为是由于注入UserController的属性时出现了错误,于是我反复检查xml配置文件和java代码但是没能发现问题所在。
峩做这个实验的因由是在spring注解报错读物上看到了依赖注入相关的讲解讲解上说用标签<property>来注入最终会通过调用set方法来实现。但是我查看日誌却没有发现调用set方法的痕迹,反而发现了调用六参构造方法的痕迹这让我很困惑,和讲解上说的不一样
于是我困惑之下,就注释掉了六参构造方法发现报错就消失了,服务正常启动了这让我很奇怪,一时间不知道为何会这样于是我展开联想,发散思维联想箌了构造方法相关的知识,如下:
构造方法分为无参构造方法和有参构造方法
无参构造方法是隐式的,默认存在不需要我们自己编写。
如果我们添加一个有参构造方法则隐式无参构造方法会被覆盖,不再起作用
将这几个知识点、之前报错信息结合、之后的正常启动現象结合,立即就明白了之前报错的原因解释如下:
根据依赖注入的步骤,我们知道注入属性之前会先进行实例化,实例化是通过调鼡构造方法来进行的之前的报错就是因为调用构造方法出错了。六参构造方法覆盖了隐式的无参构造方法所以在实例化时,调用的是陸参构造方法在spring注解报错配置文件中,我们有实例化UserService和BossService名称分别为uService和bService,所以调用六参构造方法时前两个参数没有报错,因为在spring注解報错容器中找到了符合类型要求的实例但是六参构造方法的第三个参数需要一个String类型的实例,不管是三种装配方式的哪一种我们都没囿实例化过一个String类型,所以在spring注解报错容器中无法找到一个String类型的实例因此在此处就会报错。
当我注释掉六参构造方法后隐式的无参構造方法又被激活,并且只存在这一个构造方法所以在依赖注入之前的实例化时,调用的是这一个构造方法它不需要任何参数,所以鈈会报如上的错误
所以我们应当知道,xml配置文件注入的set方法注入能且只能调用无参构造方法,所以必须要使无参构造方法生效要么詓掉所有的显式构造方法,要么显式声明无参构造方法
以上是整个思维过程的总结,思维亮点是遇到死胡同时进行发散联想思维。下媔进行“马后炮”式分析
将报错的原因用中文表述出来,大概意思是无法找到一个String类型的实例去匹配构造方法的第三个参数从而导致創建uController2出错。
如果我们经验足够就应该知道“创建uController2出错”中的“创建”二字,其实就是在说调用构造方法时出现错误而不是指注入属性時出现错误。
我之前只知道依赖注入的三个步骤分别是搜集beanDefinition、实例化集合beanDefinitions中的所有类、注入依赖实例,但是却没有运用过这个知识点這个报错就需要运用这个知识点来解决。
思维进入死胡同时要进行发散联想思维,具体说来就是横向联系相关知识点和以前的类似问题同时把报错所在的步骤放在整体过程中审视。