問(wèn)題是這樣的馍刮,我按照正常的配置文件結(jié)構(gòu)配置信夫,然后每次啟動(dòng)起來(lái)都提示找不到 Controller ,反反復(fù)復(fù)看配置文件沒(méi)發(fā)現(xiàn)問(wèn)題卡啰,依賴也正確静稻,甚至連數(shù)據(jù)庫(kù)連接池都換了,也沒(méi)解決 Controller Not Found 的問(wèn)題匈辱。振湾。。
后來(lái)過(guò)了一天我想了一下亡脸,既然是找不到 Controller 押搪,那么就是 Controller 的類沒(méi)被找到,那么如果沒(méi)被找到的話浅碾,是不是掃描的時(shí)候出了問(wèn)題呢大州?
我原來(lái)的配置是這樣的
<context:component-scan base-package="cn.lncsa.controller.*"/>
然后我試了一下增加了 Controller 的 filter
<context:component-scan base-package="cn.lncsa.controller.*">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
問(wèn)題并沒(méi)有被解決。
后來(lái)觀察垂谢,發(fā)現(xiàn) base-package 參數(shù)是 "cn.lncsa.controller.*"厦画,然后回頭對(duì)比了一下按照教程做的能正常運(yùn)行的 Helloworld ,是 "net.catten.mvc.*" 而不是"net.catten.mvc.controller.*"滥朱,我在想是不是這個(gè)通配符的問(wèn)題根暑,于是便試著把 base-package 改成 "cn.lncsa.controller"
<context:component-scan base-package="cn.lncsa.controller"/>
問(wèn)題解決。徙邻。排嫌。。
然后在想為什么呢缰犁?
是這樣的淳地,base-package 指的是掃描器從那個(gè)包開始掃描, "cn.lncsa.controller.*" 指的是掃描 controller 包下面的任何包民鼓,也就是說(shuō) * 通配符是改變了掃描基于的包了薇芝,不再是 controller 而是 controller 里面的各個(gè)子包。而我的 Controller 類是放在這個(gè)包下的丰嘉,掃的是根包里的子包的類而不是根包里的類夯到,當(dāng)然就搜索不到 Controller 了。
那么這個(gè)錯(cuò)誤的配置除了上面這么改還能怎么改呢饮亏?
<context:component-scan base-package="cn.lncsa.*">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
這樣改就好了耍贾。雖然方法不同但是原理都是更改掃描的根包阅爽。第一種方法是直接明確地指出掃描的地方。第二種方法是掃描 cn.lncsa 里面的子包荐开,但是增加 include-filter付翁, 使其只掃描 Controller 類。
當(dāng)然我的習(xí)慣是使用第一種晃听。
還有需要注意的是百侧,因?yàn)?SpringMVC 一般是和 Spring 共用, 所以會(huì)有重復(fù)掃描類的問(wèn)題能扒。我們的 Controller 是交給 SpringMVC 所屬的容器管理的佣渴,所以應(yīng)該讓主要的 Spring IOC 容器忽略掉這些 Controller。不然會(huì)造成重復(fù)掃描初斑,生成重復(fù)的對(duì)象在兩個(gè) IOC 容器里辛润。
所以除了配置 spring-mvc 的 applicationContext 以外,也要在主要的 applicationContxt 里配置掃描器见秤。
<context:component-scan base-package="cn.lncsa">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
增加 exclude-filter 就能讓主要的 IOC 容器忽略掉這些 Controller