※整合時會出現注入兩次
spring 可以有很多設定檔,可用 web.xml,或者在設定檔使用 import 標籤將其他的設定檔抓進來,但好幾個 spring 設定檔都掃瞄一樣的包,就算設了很多次,不管使用 web.xml 或 import 標籤,都只會注入一次,以上的情形,spring MVC也是一樣但這兩個設定檔是分開的,兩個都掃瞄一樣的包,會出現兩次
※java bean
package controller; @Controller @RequestMapping("/ooo/xxx/") public class XxxAction { public XxxAction() { System.out.println("XxxAction"); } }
※
※
package service; @Service public class XxxServiceImpl { public XxxServiceImpl(){ System.out.println("XxxServiceImpl"); } }
※
※設定檔
※spring 設定檔<context:component-scan base-package="controller, service" />
※
※spring MVC 設定檔
<import resource="init.TestDispatcherServlet-servlet2.xml" /> <context:component-scan base-package="controller, service" />
※
※web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>testServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/init.TestDispatcherServlet-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>*.mvc</url-pattern> </servlet-mapping>
※啟動伺服器後,會看到 console 會印出兩次 java bean 建構子的內容
※解決方式
可以使用掃瞄不同包來解決,如 spring 掃瞄 controller、spring MVC 掃瞄 service也可以使用如下的方式:
<context:component-scan base-package="controller, service" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" /> </context:component-scan>
※
※
<context:component-scan base-package="controller, service" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
※use-default-filters 預設是 true,表示可掃瞄 @Controller、@Service…等的包,將它變成 false 就沒辦法掃了,然後子標籤在和它說可以掃瞄什麼類型的注解
※如果使用 annotation,可以用 @ComponentScan(useDefaultFilters = false, includeFilters = { @Filter(type = FilterType.ANNOTATION, value = App.class) })
.FilterType.ASSIGNABLE_TYPE 將指定的 class 加入 bean id
.FilterType.CUSTOM 寫個類別繼承 TypeFilter 後,即可使用
※spring 抓 spring MVC 注入的變數
spring 就像個全域變數, spring MVC 像個區域變數區域變數知道有全域變數,但全域變數不知有區域變數
所以 spring MVC 可以抓 spring 的注入屬性;相反則不能
以上個例子來說,假設 controller 是 spring 設定檔設定的;而 service 是 spring MVC 設定的
那 service 使用 @Autowire 抓 XxxAction,伺服器啟動成功;
controller 使用 @Autowire 抓 XxxServiceImpl,伺服器啟動失敗
沒有留言:
張貼留言