1. 概述
本教程將探討標準 Spring 框架與 Spring Boot 之間的差異。
我們將重點關注並討論 Spring 的模塊(如 MVC 和 Security)在核心 Spring 環境和使用 Boot 時各自的差異。
2. Spring 簡介
簡單來説,Spring 框架為 Java 應用開發提供全面的基礎設施支持。
它包含許多實用功能,例如依賴注入,以及內置模塊,包括:
- Spring JDBC
- Spring MVC
- Spring Security
- Spring AOP
- Spring ORM
- Spring Test
這些模塊可以顯著減少應用程序的開發時間。
例如,在 Java Web 開發的早期,我們必須編寫大量的樣板代碼來插入數據源中的記錄。通過使用 Spring JDBC 模塊中的 JDBCTemplate,我們可以將其減少到幾行代碼,只需少量配置。
3. Spring Boot 簡介
Spring Boot 基本上是 Spring 框架的擴展,它消除了設置 Spring 應用程序所需的樣板配置。
它對 Spring 平台持一種觀點(opinionated),從而為更快速、更高效的開發生態系統鋪平了道路。
以下是 Spring Boot 的一些主要特性:
- 帶有觀點(opinionated)的“starter”依賴項,以簡化構建和應用程序配置
- 嵌入式服務器,避免應用程序部署的複雜性
- 指標、健康檢查和外部化配置
- 自動配置 Spring 功能——在可能的情況下
讓我們逐步熟悉這兩個框架。
4. Maven 依賴
首先,讓我們看看使用 Spring 創建 Web 應用程序所需的最小依賴項:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.5</version>
</dependency>與Spring不同,Spring Boot 只需要一個依賴項即可啓動一個Web應用程序:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.4</version>
</dependency>構建過程中,所有其他依賴項都會自動添加到最終的歸檔文件中。
另一個好的例子是測試庫。我們通常使用 Spring Test、JUnit、Hamcrest 和 Mockito 庫的集合。在 Spring 項目中,我們應該將這些庫都添加為依賴項。
或者,在 Spring Boot 中,我們只需要測試啓動器依賴項即可自動包含這些庫。
Spring Boot 提供了多種啓動器依賴項,用於不同的 Spring 模塊。其中一些最常用的包括:
- spring-boot-starter-data-jpa
- spring-boot-starter-security
- spring-boot-starter-test
- spring-boot-starter-web
- spring-boot-starter-thymeleaf
要查看所有啓動器的完整列表,請參閲 Spring 文檔。
5. MVC 配置
讓我們探討使用 Spring 和 Spring Boot 創建 JSP Web 應用程序所需的配置。
Spring 需要定義 Dispatcher servlet、映射以及其他支持性配置。我們可以使用 web.xml 文件或 Initializer 類來實現:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext context
= new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.baeldung");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container
.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}我們還需要在某個 @Configuration</em/> 類中添加 @EnableWebMvc</em/> 註解,並定義一個視圖解析器來解析控制器返回的視圖:
@EnableWebMvc
@Configuration
public class ClientWebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean
= new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return bean;
}
}相比之下,Spring Boot 僅需添加 web starter 即可配置好,只需要幾組屬性:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp以上所有 Spring 配置均通過名為 自動配置 的過程自動包含在內。
這意味着 Spring Boot 將會查看應用程序中存在的依賴項、屬性和 Bean,並根據這些內容啓用配置。
當然,如果我們想要添加自定義配置,那麼 Spring Boot 的自動配置將會退避。
5.1. 配置模板引擎
現在,讓我們學習如何在 Spring 和 Spring Boot 中配置 Thymeleaf 模板引擎。
在 Spring 中,我們需要添加 thymeleaf-spring5 依賴項以及視圖解析器的配置:
@Configuration
@EnableWebMvc
public class MvcWebConfig implements WebMvcConfigurer {
@Autowired
private ApplicationContext applicationContext;
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver =
new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
}Spring Boot 1 僅需依賴 spring-boot-starter-thymeleaf 才能啓用 Web 應用程序中 Thymeleaf 支持。由於 Thymeleaf 3.0 中的新功能,我們也需要在 Spring Boot 2 Web 應用程序中添加 thymeleaf-layout-dialect 作為依賴項。 另一種選擇是添加一個 spring-boot-starter-thymeleaf 依賴項,它可以為我們處理所有這些。
依賴項添加完成後,我們可以將模板添加到 src/main/resources/templates 文件夾中,Spring Boot 將自動顯示它們。
6. Spring Security 配置
為了簡化起見,我們將通過使用這些框架來查看默認的 HTTP Basic 身份驗證是如何啓用的。
讓我們首先看一下我們需要啓用 Spring 中 Security 所需的依賴項和配置。
Spring 需要同時使用標準 spring-security-web 和 spring-security-config 依賴項,才能在應用程序中設置 Security。
接下來,我們需要添加一個創建 SecurityFilterChain 豆(Bean)並使用 @EnableWebSecurity 註解的類:
@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1")
.password(passwordEncoder()
.encode("user1Pass"))
.authorities("ROLE_USER");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}在這裏,我們使用 inMemoryAuthentication 來設置身份驗證。
Spring Boot 也需要這些依賴項才能正常工作,但我們只需要定義 spring-boot-starter-security 依賴項,因為它會自動將所有相關的依賴項添加到類路徑中。
Spring Boot 中的安全配置與上述配置相同。
要了解如何在 Spring 和 Spring Boot 中實現 JPA 配置,可以查看我們的文章《Spring 中 JPA 的指南》。
7. 應用啓動 (Application Bootstrap)
Spring 和 Spring Boot 應用啓動的基本區別在於 Servlet 的使用。Spring 使用 web.xml 或 SpringServletContainerInitializer 作為啓動入口點。
另一方面,Spring Boot 只使用 Servlet 3 的特性來啓動應用。我們來詳細探討一下。
7.1. 如何啓動 Spring Boot 應用?
Spring 支持傳統的 <em>web.xml</em> 方式以及最新 Servlet 3+ 的啓動方法。
讓我們逐步查看 <em>web.xml</em> 方式:
- Servlet 容器(服務器)讀取 `web.xml`。
- `DispatcherServlet`,該對象定義在 `web.xml` 中,由容器實例化。
- `DispatcherServlet` 通過讀取 `
` 創建 ` 。 - 最後,`DispatcherServlet` 註冊了應用程序上下文中的 Bean。
以下是 Spring 使用 Servlet 3+ 方式的啓動方法:
- 容器搜索實現 `ServletContainerInitializer` 的類並執行它們。
- `SpringServletContainerInitializer` 找到所有實現 `WebApplicationInitializer` 的類。
- `WebApplicationInitializer` 使用 XML 或 `@Configuration` 類創建上下文。
- `WebApplicationInitializer` 創建 `DispatcherServlet`,並使用先前創建的上下文。
7.2. Spring Boot 啓動方式?
Spring Boot 應用的入口類是帶有 @SpringBootApplication 註解的類。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}默認情況下,Spring Boot 使用嵌入式容器運行應用程序。在這種情況下,Spring Boot 使用 public static void main入口點來啓動嵌入式 Web 服務器。
它還負責將 Servlet、Filter和 ServletContextInitializer bean 從應用程序上下文綁定到嵌入式 Servlet 容器。
Spring Boot 另一個特性是它自動掃描主類及其同級或子包中的所有類以查找組件。
此外,Spring Boot 提供了將其部署為外部容器中的 Web 存檔的選項。在這種情況下,我們需要擴展 SpringBootServletInitializer。
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
// ...
}外部 Servlet 容器會查找 Web 存檔的 META-INF 文件中定義的 Main-class,並且 SpringBootServletInitializer 將負責綁定 Servlet、Filter 和 ServletContextInitializer。
8. 打包與部署
最後,讓我們看看如何打包和部署應用程序。這兩個框架都支持常見的包管理技術,如 Maven 和 Gradle;然而,在部署方面,這兩個框架存在很大差異。
例如,Spring Boot Maven 插件 為 Maven 提供 Spring Boot 支持。它還允許打包可執行的 jar 或 war 歸檔文件,並在“原地”運行應用程序。
與 Spring 在部署上下文下的優勢包括:
- 提供嵌入式容器支持
- 配置獨立運行 jar 文件,使用命令 java -jar
- 選項可以排除依賴項以避免外部容器部署時的潛在 jar 衝突
- 選項可以指定部署時的活動配置文件
- 用於集成測試的隨機端口生成
9. 結論
在本文中,我們學習了 Spring 和 Spring Boot 之間的區別。
簡單來説,我們可以説 Spring Boot 是 Spring 本身的擴展,旨在簡化開發、測試和部署過程。