Spring Boot vs Spring MVC:五大核心差異詳解與項目遷移實戰(zhàn)指南
1.1 Spring MVC是否需要獨立容器而Spring Boot自帶?
Spring MVC作為基礎(chǔ)的Web框架,本身并不包含服務(wù)器容器。開發(fā)時需要手動配置Tomcat/Jetty等容器,通過部署war包到獨立服務(wù)器運行。曾經(jīng)在項目中配置Tomcat插件浪費了半小時,只因為忘記在pom.xml中添加servlet-api依賴。
而Spring Boot直接把Tomcat/Jetty打成jar包內(nèi)嵌其中。用main方法啟動項目時,就像啟動普通Java應(yīng)用那樣簡單。這種設(shè)計讓本地調(diào)試變得極其方便,不再需要頻繁進行mvn package部署到外部容器。最近幫同事排查問題時發(fā)現(xiàn),他們用Spring Boot寫的接口可以直接在IDE里右鍵運行調(diào)試,省去了傳統(tǒng)部署流程的麻煩。
1.2 配置方式有何本質(zhì)不同?
傳統(tǒng)Spring MVC項目中,web.xml里需要配置DispatcherServlet并指定配置文件路徑,spring-servlet.xml里要聲明視圖解析器、組件掃描等二十多項基礎(chǔ)配置。還記得三年前維護過的一個老項目,XML配置文件加起來超過800行,光是處理組件掃描路徑?jīng)_突就花了三天時間。
Spring Boot改用JavaConfig和自動配置機制后,新建項目時application.properties只需要設(shè)置server.port和spring.thymeleaf.cache=false這樣的關(guān)鍵參數(shù)。上周重構(gòu)登錄模塊時,添加spring-boot-starter-data-jpa依賴后就直接能用JPA接口,完全不用手動配置EntityManagerFactory。
1.3 自動配置機制如何簡化開發(fā)?
自動配置的核心在于條件化Bean創(chuàng)建。當(dāng)classpath存在特定類時,Spring Boot會自動配置相關(guān)組件。比如項目中引入spring-boot-starter-web依賴后,默認會配置Jackson進行JSON序列化,省去了手動注冊MappingJackson2HttpMessageConverter的步驟。
最近在開發(fā)消息推送模塊時深有體會:添加spring-boot-starter-websocket依賴后,只需要寫@EnableWebSocket注解,所有的WebSocket配置自動生效。這種智能裝配機制讓依賴管理變得輕松,但也需要注意排除不需要的自動配置,之前就碰到過Redis自動配置干擾本地測試的情況。
1.4 啟動流程有哪些關(guān)鍵差異?
傳統(tǒng)Spring MVC的啟動過程分為容器初始化和應(yīng)用初始化兩個階段。Servlet容器先加載web.xml,然后通過ContextLoaderListener創(chuàng)建根應(yīng)用上下文,整個過程需要經(jīng)歷Servlet生命周期的各個階段。
Spring Boot的啟動入口是main方法里的SpringApplication.run()。啟動時先創(chuàng)建內(nèi)嵌Servlet容器,然后通過SpringFactoriesLoader加載自動配置類。這個過程中最明顯的變化是日志輸出,能看到Started Application in 2.5 seconds字樣而不是傳統(tǒng)的容器啟動日志。
1.5 默認約定優(yōu)于配置體現(xiàn)在哪些方面?
默認靜態(tài)資源路徑從/webapp下移到了/resources/static目錄,這個改變讓前后端分離部署更自然。視圖解析器默認配置為從/templates加載模板文件,上周用Thymeleaf開發(fā)管理后臺時,直接把html文件放在約定目錄就自動識別了。
數(shù)據(jù)源配置的默認行為特別值得稱贊。當(dāng)檢測到內(nèi)存數(shù)據(jù)庫依賴時,Spring Boot會自動配置H2控制臺。上次做快速原型驗證,添加h2依賴后直接訪問/h2-console就能操作數(shù)據(jù)庫,完全跳過了JDBC連接配置的繁瑣步驟。
2.1 依賴管理需要怎樣調(diào)整?
傳統(tǒng)Spring MVC項目的pom.xml里通常堆積著spring-core、spring-webmvc等分散的依賴項。遷移時要把這些替換成spring-boot-starter-web,這個Starter會自動引入嵌入式Tomcat、Jackson以及Spring MVC核心組件。上周幫團隊重構(gòu)用戶中心模塊時,原本需要手動管理的15個依賴縮減到3個Starter。
注意處理版本沖突問題。Spring Boot的dependencyManagement會自動管理所有Starter版本,但老項目中可能有特定版本的MyBatis或Hibernate依賴。遇到這種情況時,在pom.xml里顯式聲明需要的版本號會覆蓋Spring Boot默認版本。之前升級數(shù)據(jù)訪問層時,用
2.2 web.xml配置如何轉(zhuǎn)化?
那些在web.xml里聲明的DispatcherServlet、Filter和Listener,現(xiàn)在要改寫成Java配置類。用@SpringBootApplication注解的主類已經(jīng)繼承了SpringBootServletInitializer,自動處理了Servlet3.0+的容器初始化。之前配置的CharacterEncodingFilter,現(xiàn)在通過FilterRegistrationBean在配置類中注入。
XML配置遷移有個實用技巧:逐塊轉(zhuǎn)換而不是整體替換。把原spring-mvc.xml里的<mvc:annotation-driven>對應(yīng)成@EnableWebMvc注解,組件掃描改成@ComponentScan配置。最近重構(gòu)商品服務(wù)時,保留原有XML配置文件的同時,用@ImportResource逐步引入到Spring Boot環(huán)境,實現(xiàn)了平滑過渡。
2.3 視圖解析器怎樣配置更高效?
Spring Boot默認配置了Thymeleaf或FreeMarker的視圖解析器,但老項目可能還在用JSP。添加spring-boot-starter-tomcat依賴后,在application.properties設(shè)置spring.mvc.view.prefix=/WEB-INF/views/就能繼續(xù)支持JSP。上個月改造訂單系統(tǒng)的報表模塊時,發(fā)現(xiàn)只需要調(diào)整模板文件存放路徑,原有JSTL標(biāo)簽完全兼容。
對于需要自定義視圖解析的場景,創(chuàng)建配置類實現(xiàn)WebMvcConfigurer接口更靈活。通過重寫configureViewResolvers方法,可以添加多個視圖解析器并設(shè)置優(yōu)先級。曾經(jīng)在混合使用PDF導(dǎo)出和HTML模板的項目中,這種配置方式讓不同格式的視圖解析互不干擾。
2.4 如何保持原有MVC功能的同時使用Starter?
用@Configuration注解創(chuàng)建保留原有功能的配置類是關(guān)鍵。當(dāng)Spring Boot的自動配置與現(xiàn)有配置沖突時,通過@ConditionalOnMissingBean注解控制Bean的加載順序。上季度遷移審批流程模塊時,原有XML里定義的HandlerMapping通過@Bean方式重新聲明,成功與自動配置的RequestMappingHandlerMapping共存。
分階段遷移策略能降低風(fēng)險。先保持原有Controller和Service不變,僅替換數(shù)據(jù)訪問層為Spring Data JPA。待核心功能驗證通過后,再用@RestControllerAdvice逐步替換原有的HandlerExceptionResolver。這種漸進式改造讓團隊在三個月內(nèi)完成了大型ERP系統(tǒng)的遷移。
2.5 測試策略需要哪些改變?
拋棄傳統(tǒng)的SpringJUnit4ClassRunner,改用@SpringBootTest注解啟動完整應(yīng)用上下文。測試REST API時,自動配置的TestRestTemplate比手動構(gòu)造的MockMvc更貼近真實環(huán)境。上星期測試支付回調(diào)接口,發(fā)現(xiàn)TestRestTemplate能正確處理SSL證書,這是舊測試框架做不到的。
多層測試體系變得更清晰。單元測試用Mockito驗證Service層邏輯,集成測試用@DataJpaTest專注數(shù)據(jù)庫操作,Web層測試用@WebMvcTest配合MockBean。重構(gòu)用戶權(quán)限模塊時,這種分層測試策略讓代碼覆蓋率從45%提升到78%,且測試用例運行時間縮短了60%。