1. 概述
本篇文章主要探讨标准 Spring 框架与 Spring Boot 的区别。
我们将重点分析在使用核心 Spring 和使用 Spring Boot 时,Spring 的各个模块(如 MVC、Security)的配置差异。
2. 什么是 Spring?
简单来说,Spring 框架为开发 Java 应用提供了全面的基础设施支持。
它包含了许多强大的特性,例如依赖注入(Dependency Injection),以及一系列开箱即用的模块:
- 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 平台持“约定优于配置”的理念,从而打造了一个更快速、高效的开发环境。
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 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 中,只需引入一个测试 starter 依赖即可自动包含这些库。
✅ Spring Boot 提供了多个针对不同 Spring 模块的 starter 依赖。 最常用的几个包括:
spring-boot-starter-data-jpa
spring-boot-starter-security
spring-boot-starter-test
spring-boot-starter-web
spring-boot-starter-thymeleaf
完整 starter 列表可参考 Spring 官方文档。
5. MVC 配置
下面来看一下使用 Spring 和 Spring Boot 创建 JSP Web 应用所需的配置。
5.1. Spring 的配置方式
Spring 需要手动定义 DispatcherServlet
、映射关系以及其他支持配置。可以通过 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
类上添加 @EnableWebMvc
注解,并定义一个视图解析器来处理控制器返回的视图:
@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;
}
}
5.2. Spring Boot 的配置方式
相比之下,Spring Boot 只需添加 Web starter 后配置几个属性即可完成设置:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
✅ 上述所有 Spring 配置都通过一个叫 auto-configuration(自动配置) 的机制被自动包含进来。
这意味着 Spring Boot 会根据项目中的依赖、属性和 Bean 来自动完成配置。
当然,如果你需要自定义配置,Spring Boot 的自动配置会主动让位。
5.3. 模板引擎配置
接下来我们看看如何在 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 中的配置
Spring Boot 1 只需引入 spring-boot-starter-thymeleaf
依赖即可启用 Thymeleaf。
由于 Thymeleaf 3.0 的新特性,在 Spring Boot 2 中还需添加 thymeleaf-layout-dialect
依赖。或者,也可以直接使用 spring-boot-starter-thymeleaf
,它会自动处理这些依赖。
依赖配置完成后,只需将模板文件放入 src/main/resources/templates
目录下,Spring Boot 就会自动识别并渲染。
6. Spring Security 配置
为了简化说明,我们来看看如何在这两个框架中启用默认的 HTTP Basic 认证。
Spring 中的配置
Spring 需要引入以下两个依赖来启用安全功能:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
然后创建一个配置类,定义 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 即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
✅ 这个 starter 会自动将所有相关依赖加入 classpath。
配置方式与 Spring 完全一致。
关于 JPA 的配置方式,可以参考我们的文章 A Guide to JPA with Spring。
7. 应用启动方式
Spring 和 Spring Boot 在应用启动方式上的主要区别在于 Servlet 的引导机制。
7.1. Spring 的启动方式
Spring 支持传统的 web.xml
启动方式和基于 Servlet 3+ 的方式。
web.xml 启动流程
- 容器读取
web.xml
- 实例化
web.xml
中定义的DispatcherServlet
DispatcherServlet
根据WEB-INF/{servletName}-servlet.xml
创建WebApplicationContext
- 最后注册应用上下文中的 Bean
Servlet 3+ 启动流程
- 容器查找并执行实现了
ServletContainerInitializer
的类 SpringServletContainerInitializer
查找所有实现WebApplicationInitializer
的类WebApplicationInitializer
使用 XML 或@Configuration
类创建上下文- 创建
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 使用内嵌容器运行应用。此时通过 public static void main
方法启动内嵌 Web 服务器。
它还会自动将应用上下文中的 Servlet
、Filter
和 ServletContextInitializer
绑定到内嵌容器。
另一个亮点是:✅ Spring Boot 会自动扫描主类所在包及其子包下的所有组件。
此外,Spring Boot 还支持打包为 WAR 并部署到外部容器。此时需要继承 SpringBootServletInitializer
:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
// ...
}
此时外部容器会从 WAR 的 META-INF
文件中查找主类,而 SpringBootServletInitializer
负责绑定 Servlet
、Filter
和 ServletContextInitializer
。
8. 打包与部署
最后我们来看打包与部署方式。两个框架都支持 Maven 和 Gradle,但在部署方面有显著差异。
例如,Spring Boot Maven Plugin 提供了对 Maven 的支持,可以打包为可执行的 jar 或 war,并支持“原地运行”。
✅ Spring Boot 相比 Spring 在部署方面的优势包括:
- ✅ 内嵌容器支持
- ✅ 通过
java -jar
独立运行 jar - ✅ 可排除依赖以避免外部容器中的 jar 冲突
- ✅ 支持部署时指定 active profiles
- ✅ 集成测试时支持随机端口生成
9. 总结
本文对比了 Spring 与 Spring Boot 的关键差异。
一句话总结:Spring Boot 是 Spring 的扩展,旨在让开发、测试和部署更加便捷高效。