总结一下今天下午的研究成果,整合SSM项目时候,最后测试从库中查询数据报了一个这样的异常,很是让我头大,足足百度+stackoverflow了一下午,愣是没有研究出成果,最后快要吃饭的时候静下心来想一想,到底是哪里出了问题,从最开始的流程去想。。。检查的时候,恍然大悟,所以想记录的是今天的解决问题的思路与方法。
先来看一下我的异常问题的截图
具体异常代码如下
<span style="color:#000000"><code>org.springframework.beans.factory.BeanCreationException:
Error creating bean with name <span style="color:#009900">'itemController'</span>:
Could not autowire field: <span style="color:#000088">private</span> com.taotao.service.ItemService com.taotao.controller.ItemController.itemService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.taotao.service.ItemService] found <span style="color:#000088">for</span> dependency:
expected <span style="color:#000088">at</span> least <span style="color:#006666">1</span> bean which qualifies <span style="color:#000088">as</span> autowire candidate <span style="color:#000088">for</span> this
dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=<span style="color:#009900">true</span>)}
<span style="color:#000088">at</span> .........................省略</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
解决思路:
先看异常信息的时候:大概意思是说Bean容器创建异常,@autowired的注解注入Service层失败了,同时在后面又报出了Controller层也是没有注解注入!所有都是围绕着这个@autowired不能自动注入,而在我的代码中是这样写到的:
Service层的实现类
<span style="color:#000000"><code><span style="color:#9b859d">@Service</span>
<span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">ItemServiceImpl</span> <span style="color:#000088">implements</span> <span style="color:#4f4f4f">ItemService</span> {
<span style="color:#9b859d">@Autowired</span>
<span style="color:#000088">private</span> ItemMapper itemMapper;
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
Controller层:
<span style="color:#000000"><code><span style="color:#9b859d">@Controller</span>
<span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">ItemController</span> {
<span style="color:#9b859d">@Autowired</span>
<span style="color:#000088">private</span> ItemService itemService;
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
通过上面的@Service(来自SpringMVC的注解)来实现Service层的实现类注入到Spring容器中。而此时这里的@Autowired的DAO层接口的代理对象并没有报错,当时在网上查找了一番,以为是因为DAO层没有用@Compent或者@Repository这样的注解造成的错误,后来思考了一下,发现因为是用Mapper映射做的DAO层接口的实现类,所以完全没有必要去做这个注解,那么问题也就与DAO层无关了。
而@Controller这里的注解是没有报错的。。也就是说我在spring-mvc.xml配置文件中的包扫描注解是没有问题的。代码如下:
<span style="color:#000000"><code> <span style="color:#880000"><!-- 扫描包Controller --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">context:component-scan</span> <span style="color:#4f4f4f">base-package</span>=<span style="color:#009900">"com.xxxxx.controller"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">context:component-scan</span>></span>
<span style="color:#880000"><!-- 配置mvc注解驱动 --></span>
<span style="color:#880000"><!-- 例如@resquestmapping这类的 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">mvc:annotation-driven</span> /></span></code></span>
- 1
- 2
- 3
- 4
- 5
但是Controller层报错的信息是注入到它里的Service层,也就是@Autowired这个注解。可是为什么@Autowired会失效呢?那么仔细想一下肯定是Service层并没有注入到Spring容器中去!所以追溯到Service的实现类去。也就是说Service的实现类并没有成功注入到Spring容器中。
既然是@Service的注解没有生效,那么问题应该是出现在applicationContext-service.xml里的包扫描了,然而检查了一下代码,也并没有问题,代码如下:
<span style="color:#000000"><code><span style="color:#880000"><!-- 扫描包Service实现类 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">context:component-scan</span> <span style="color:#4f4f4f">base-package</span>=<span style="color:#009900">"com.xxxxx.service"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">context:component-scan</span>></span></code></span>
- 1
- 2
此时我的心情是崩溃的- -。。。马上该吃饭的时候,突然想到。。。这些配置既然没有错的话,为什么不行?根本问题到底在哪里!突然想到了万一是Spring-*,xml的配置文件没有加载进来呢,也会导致包扫描注解失效,注入Spring容器中失效!所以果不其然,看了一眼web.xml里的配置。
<span style="color:#000000"><code> <span style="color:#880000"><!-- 加载spring容器 --></span>
<span style="color:#880000"><!-- 初始化加载application.xml的各种配置文件 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">context-param</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">param-name</span>></span>contextConfigLocation<span style="color:#006666"></<span style="color:#4f4f4f">param-name</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">param-value</span>></span>classpath:spring/application-*.xml<span style="color:#006666"></<span style="color:#4f4f4f">param-value</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">context-param</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">listener</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">listener-class</span>></span>org.springframework.web.context.ContextLoaderListener<span style="color:#006666"></<span style="color:#4f4f4f">listener-class</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">listener</span>></span>
<span style="color:#880000"><!-- 配置springmvc前端控制器 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">servlet</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">servlet-name</span>></span>taotao-manager<span style="color:#006666"></<span style="color:#4f4f4f">servlet-name</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">servlet-class</span>></span>org.springframework.web.servlet.DispatcherServlet<span style="color:#006666"></<span style="color:#4f4f4f">servlet-class</span>></span>
<span style="color:#880000"><!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation,
springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">init-param</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">param-name</span>></span>contextConfigLocation<span style="color:#006666"></<span style="color:#4f4f4f">param-name</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">param-value</span>></span>classpath:spring/springmvc.xml<span style="color:#006666"></<span style="color:#4f4f4f">param-value</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">init-param</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">load-on-startup</span>></span>1<span style="color:#006666"></<span style="color:#4f4f4f">load-on-startup</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">servlet</span>></span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
看到web.xml中的classpath:spring/application-*.xml时恍然大悟了。。因为我的配置文件在配置的时候名字是这样的。!看图。!
问题就是如此的蛋疼。。。因为自己的马虎,之前配的时候没有仔细看,所以导致了没有加载上applicationContext-service.xml。。。
改正后
<span style="color:#000000"><code> <context-<span style="color:#4f4f4f">param</span>>
<<span style="color:#4f4f4f">param</span>-name>contextConfigLocation</<span style="color:#4f4f4f">param</span>-name>
<<span style="color:#4f4f4f">param</span>-<span style="color:#4f4f4f">value</span>>classpath:spring/applicationContext-*.xml</<span style="color:#4f4f4f">param</span>-<span style="color:#4f4f4f">value</span>>
</context-<span style="color:#4f4f4f">param</span>></code></span>
- 1
- 2
- 3
- 4
无报错信息。。。。。。。。
之前看到网上许多人报这个错误的原因多数都是没有进行对应逻辑层与配置文件的包扫描,比如Service层里对应的applicationContext-service.xml里应该配置component-scan的包扫描。
结论:
遇到异常问题的时候,先看报错信息,一步一步分析,看看到底是代码写的有问题像这种情况一样,想一想问题的根本之源在哪里。。。相信有逻辑性的去判断解决一个问题,那也仅仅是时间问题吧!……..
——————————————————本文为了记录一下现在的解决思路。。。给以后的自己看!~