目錄
一、SpringMVC、Spring的bean加載控制。
(1)實際開發的包結構層次。
(2)如何"精準"控制兩個容器分別加載各自bean。(分析)
<1>SpringMVC相關bean加載控制。(方法)
<2>Spring相關bean加載控制。(方法)
二、Spring配置類——bean加載控制。
(1)方法一:設定精確范圍。
<1>controller層。
<2>Spring配置類。
<3>SpringMVC配置類。
(2)方法二:直接掃描主包(com.xxx),再排除controller包。
<1>排除過濾器(excludeFilters)與包含過濾器(includeFilters)。
<2>設置過濾規則(type)與過濾類型(classes)。
<3>最終的Spring配置類。
三、Web容器初始化配置類加載Spring環境。
<1>方法createRootApplicationContext()。
<2>Web容器配置類實現AbstractDispatcherServletInitializer類。(bean加載格式)
<3>實現類AbstractAnnotationConfigDispatcherServletInitializer 。(更簡單操作)
一、SpringMVC、Spring的bean加載控制。
(1)實際開發的包結構層次。
- 在簡單的SpringMVC入門案例中:整體項目的核心包結構只有controller層與config層。
- SpringMVC學習(入門案例思路及實現、Web容器初始化與SpringMVC配置類)(2)-CSDN博客
- 但實際上真正的項目沒有這么簡單。其項目的主要包結構如下所示:
- config目錄。包含Web容器初識化配置類、Spring配置類、SpringMVC配置類。(取代傳統開發的XML配置文件)
- controller目錄。其內部是所有SpringMVC需要加載的bean。
- service、dao等目錄。其內部都是各種業務bean、功能bean。而這些bean都是需要讓Spring加載。
- 其中Spring需要管理的業務bean(service層)。需要管理的功能bean(第三方bean)如:DataSource(數據源對象)、SqlSessionFactoryBean等等MyBatis相關bean。
(2)如何"精準"控制兩個容器分別加載各自bean。(分析)
<1>SpringMVC相關bean加載控制。(方法)
- 讓controller層的bean被SpringMVC加載控制很容易做到。——控制SpringMVC加載的bean對應包位于對應的自己項目的controller目錄下即可。
<2>Spring相關bean加載控制。(方法)
- 讓Spring只加載對應的業務bean、功能bean。而避免加載到SpringMVC管理的bean。
- 方式一:Spring加載的bean設定掃描范圍為com.xxx,再排除掉controller包內的bean。
- 方式二:Spring加載的bean設定掃描范圍為精準范圍。就是掃描包設定每層的精確范圍:com.xxx.service包、com.xxx.dao包等。
- 方式三:不區分Spring與springMVC的環境,加載到同一個環境中。
二、Spring配置類——bean加載控制。
(1)方法一:設定精確范圍。
- 縮小具體包對應的范圍。這樣就不會掃描到SpringMVC管理的bean所在controller層中。
<1>controller層。
- ExampleController類。
package com.hyl.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;/*** 控制器類*/ //1.使用注解@Controller定義bean @Controller public class ExampleController {/*** 隨機寫一個處理請求的方法* @return 字符串(模仿json數據)*///設置當前方法操作的訪問路徑@RequestMapping("/save")//設置當前操作的返回值類型(如何響應給客戶端)@ResponseBodypublic String save(){//方便測試查看運行結果。System.out.println("exampleController save ...");return "{'module':'springMVC'}";}}
<2>Spring配置類。
package com.hyl.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;//創建Spring的配置類 //排除加載controller包對應bean,使controller層交給SpringMVC管理@Configuration @ComponentScan({"com.hyl.service","com.hyl.dao"}) /*@ComponentScan("com.hyl")*/ public class SpringConfig { }
<3>SpringMVC配置類。
package com.hyl.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;//創建SpringMVC的配置類,加載controller包對應bean@Configuration @ComponentScan("com.hyl.controller") public class SpringMvcConfig { }
- 測試類。(App)
package com.hyl.test;import com.hyl.config.SpringConfig; import com.hyl.controller.ExampleController; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {@Testpublic void test(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);ExampleController exampleController = context.getBean(ExampleController.class);System.out.println(exampleController);}}
- 測試運行結果。無法獲取controller層的對應bean。
(2)方法二:直接掃描主包(com.xxx),再排除controller包。
- 按住ctrl進入注解@ComponentScan查看其內部的可用屬性。
<1>排除過濾器(excludeFilters)與包含過濾器(includeFilters)。
<2>設置過濾規則(type)與過濾類型(classes)。
- excludeFilters取值:注解@ComponentScan的Filter。
- 屬性type、classes根屬地。
- 過濾規則。分為很多個過濾策略:FilterType.xxx。(包括按注解過濾規則、用戶自定義過濾規則、正則過濾規則等等)
- 過濾類型。當過濾規則設定為:按注解進行過濾時。就需要再手動指定需要過濾的注解是哪個類型(注解:@Controller),才能完成注解的過濾掃描。
<3>最終的Spring配置類。
- 簡單說以上操作的目的:當Spring掃描整個包"com.xxx"下所有包時,需要按照注解排除掃描——注解@Controller下標明的bean。
package com.hyl.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller;//創建Spring的配置類 //排除加載controller包對應bean,使controller層交給SpringMVC管理@Configuration /*@ComponentScan({"com.hyl.service","com.hyl.dao"})*/ @ComponentScan(value = "com.hyl",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class) ) public class SpringConfig { }
- 測試類。
package com.hyl.test;import com.hyl.config.SpringConfig; import com.hyl.controller.ExampleController; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {@Testpublic void test(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);ExampleController exampleController = context.getBean(ExampleController.class);System.out.println(exampleController);}}
- 測試前需要將SpringMVC的配置類的注解@Configuration注釋,否則即使在spring配置類中使用了注解攔截掃描,但最終還是會因為該注解自動將bean交給Spring容器管理。
- 注釋@Configuration后,繼續獲取Controller層的對應bean就會報錯。
- 為了既可以攔截注解生效,又可以讓SpringMVC配置類被掃描到,可以將其提到上一級目錄或者上上級目錄即可。(如:放置com包下,不放在com.xxx下的某個目錄)
三、Web容器初始化配置類加載Spring環境。
- 在SpringMVC的入門案例中。配置Tomcat運行的Web容器初識化啟動配置類中,當時只配置了SpringMVC的環境。這次順手將Spring的環境一起配置了。
<1>方法createRootApplicationContext()。
- createRootApplicationContext()方法作用就是配置Spring的環境,加載Spring配置類。
- 與加載SpringMVC配置類的操作一模一樣。不一樣的地方就是修改:配置類.class。
<2>Web容器配置類實現AbstractDispatcherServletInitializer類。(bean加載格式)
- 這樣當服務器啟動時,不僅有SpringMVC容器,還有Spring容器。
- createServletApplicationContext()——>加SpringMVC容器。
- createRootApplicationContext()——>Spring容器。
package com.hyl.config;import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;//定義一個Servlet容器啟動的配置類,在里面加載SpringMVC的配置 public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {/***加載SpringMVC配置類* @return*/@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();webApplicationContext.register(SpringMvcConfig.class);return webApplicationContext;}/***加載Spring配置類(加載Spring容器)* @return*/@Overrideprotected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();webApplicationContext.register(SpringConfig.class);return webApplicationContext;}/*** 設置哪些請求歸屬SpringMVC處理* @return*/@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}}
<3>實現類AbstractAnnotationConfigDispatcherServletInitializer 。(更簡單操作)
- 簡化后的Web容器配置類。
package com.hyl.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;//定義一個Servlet容器啟動的配置類,在里面加載SpringMVC、Spring的配置 public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {/***加載Spring配置類(加載Spring容器)* @return*/@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[]{SpringConfig.class};}/***加載SpringMVC配置類* @return*/@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMvcConfig.class};}@Overrideprotected String[] getServletMappings() {return new String[]{"/"};} }