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平台的观点,为更快、更高效的开发生态系统铺平了道路。
以下是Spring Boot中的一些功能:
- 固执己见的“启动器”依赖项,可简化构建和应用程序配置
- 嵌入式服务器,以避免应用程序部署的复杂性
- 指标、健康检查和外部化配置
- 自动配置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需要定义DispatcherServlet、映射和其他支持配置。我们可以使用web.xml文件或WebApplicationInitializer类来做到这一点:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("cn.tuyucheng.taketoday");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container
.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
我们还需要将@EnableWebMvc注解添加到@Configuration类,并定义一个视图解析器来解析从控制器返回的视图:
@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;
}
}
相比之下,一旦我们添加了web starter,Spring Boot只需要几个属性就可以让一切正常进行:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
上面所有的Spring配置都是通过一个名为自动配置的过程添加Boot web starter来自动包含的。
这意味着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基本身份验证。
让我们首先看一下使用Spring启用安全性所需的依赖项和配置。
Spring需要标准的spring-security-web和spring-security-config依赖项来在应用程序中设置安全性。
接下来我们需要添加一个类来创建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. Spring和Spring Boot的引导
在Spring和Spring Boot中引导应用程序的基本区别在于Servlet。Spring使用web.xml或SpringServletContainerInitializer作为其引导入口点。
另一方面,Spring Boot仅使用Servlet 3功能来引导应用程序。让我们详细谈谈这一点。
7.1 Spring如何引导?
Spring既支持遗留的web.xml引导方式,也支持最新的Servlet 3+方法。
让我们分步查看web.xml方法:
- Servlet容器(服务器)读取web.xml。
- web.xml中定义的DispatcherServlet由容器实例化。
- DispatcherServlet通过读取WEB-INF/{servletName}-servlet.xml来创建WebApplicationContext。
- 最后,DispatcherServlet注册在应用程序上下文中定义的beans。
以下是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的另一个功能是它会自动扫描同一个包中的所有类或Main类的子包中的组件。
此外,Spring Boot提供了将其部署为外部容器中的Web存档的选项。在这种情况下,我们必须扩展SpringBootServletInitializer:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
// ...
}
在这里,外部Servlet容器查找Web存档的META-INF文件中定义的主类,而SpringBootServletInitializer将负责绑定Servlet、Filter和ServletContextInitializer。
8. 打包部署
最后,让我们看看如何打包和部署应用程序。这两个框架都支持常见的包管理技术,如Maven和Gradle;但是,在部署方面,这些框架有很大不同。
例如,Spring Boot Maven插件在Maven中提供了Spring Boot支持。它还允许打包可执行jar或war存档并“就地”运行应用程序。
在部署上下文中,Spring Boot相对于Spring的一些优势包括:
- 提供嵌入式容器支持
- 使用命令java -jar独立运行jar的预配
- 在外部容器中部署时排除依赖项以避免潜在的jar冲突的选项
- 部署时指定激活Profile的选项
- 用于集成测试的随机端口生成
9. 总结
在本文中,我们了解了Spring和Spring Boot之间的区别。
简单来说,Spring Boot就是对Spring本身的扩展,让开发、测试、部署更加方便。