Spring 和 Spring Boot的比较

一、概述
在这里,我们将会看到标准的spring框架与spring boot之间的不同
我们将关注并讨论spring的一些模块,比如MVC和安全这些核心模块,在使用的时候与spring boot的不同

二、什么是spring
简单的说,spring框架为开发java应用提供了的基础框架
它包含了一些非常给力的功能,如依赖注入和开箱即用的模块,如:
Spring JDBC
Spring MVC
Spring Security
Spring AOP
Spring ORM
Spring Test
这些模块彻底降低了开发一个应用需要花费的时间
例如:在早起开发java web应用,我们需要写很多的样板代码来在数据库里面插入一条记录。但是如果使用了Spring JDBC的JDBCTemplate ,
我们只需要几行代码和一点点的配置。
三、什么是spring boot?
Spring Boot基本上是Spring框架的扩展,它消除了设置Spring应用程序所需的样板配置。就是进一步降低开发人员的配置工作
它以一种特殊的视角看待spring平台,那就是为开发生态找到一条更快和更有效的道路
以下是SpringBoot中的一些特性:
特有的“starter”依赖关系,以简化构建和应用程序配置
嵌入式服务器以避免应用程序部署的复杂性
度量、健康检查和外部化配置
Spring功能尽可能的自动配置
让我们逐步对比这两个框架
四、maven依赖
1、首先我们来看一下使用spring创建web应用需要的最少依赖:

    org.springframework
    spring-web
    5.1.0.RELEASE


    org.springframework
    spring-webmvc
    5.1.0.RELEASE

2、不像spring,spring boot仅仅需要一个依赖就能把web应用给建好并运行起来:

    org.springframework.boot
    spring-boot-starter-web
    2.0.5.RELEASE

剩下的其他的依赖在最终构建的时候自动的添加到war包里面

另外一个好的例子是测试相关jar,通常情况下我们会使用一系列的Spring Test, JUnit, Hamcrest, and Mockito相关jar,在spring项目中,我们需要把这些依赖的jar都添加进来。
但是在spring boot里面,我们仅仅需要一个 测试的starter依赖,它会自动的包含这些依赖jar

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列表,可以访问https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter 获取

五、MVC配置

1、我们来探究一下使用spring和spring boot创建一个JSP web应用需要的配置
spring要求定义 dispatcher servlet ,mappings,和其他相关配置项,我们可以使用web.xml或者一个初始化类来实现:
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("/");
    }
}

我们还需要添加@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的自动配置就会被忽略

2、配置模板引擎
让我们来学习一下在spring和springboot中如何去配置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);
    }
}

在web应用中,Spring Boot 1的要求仅仅是添加spring-boot-starter-thymeleaf依赖来启动Thymeleaf 的支持,但是如果想使用Thymeleaf3.0的新特性,在Spring Boot 2的web应用中也仅仅需要添加 thymeleaf-layout-dialect 依赖

一旦依赖添加进来之后,我们就可以在rc/main/resources/templates 文件夹下面添加模板了,springboot会自动的显示他们

六、spring security 配置
为了简单起见,我们来看看如何使用这些框架来启用默认的HTTP基本身份验证。

首先我们来看看当我们使用spring启动security时需要的依赖和配置:

在应用中,spring需要标准的 spring-security-web 和spring-security-config依赖来启动security

下一步我们需要一个扩展自WebSecurityConfigurerAdapter 的类,并添加上@EnableWebSecurity标签
@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
  
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1")
            .password(passwordEncoder()
            .encode("user1Pass"))
          .authorities("ROLE_USER");
    }
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .anyRequest().authenticated()
          .and()
          .httpBasic();
    }
     
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

这里我们使用inMemoryAuthentication 来建立身份验证
相似的,spring boot也需要这些依赖才能进行工作,但是我们仅仅需要依赖spring-boot-starter-security ,spring-boot-starter-security 将会自动的添加相关的依赖到classpath,security相关的配置和上面一模一样。

七、应用启动
在spring和springboot中启动应用的基本不同在于servlet. spring要么使用web.xml要么使用SpringServletContainerInitializer 作为启动的入口
而spring boot则仅仅支持servlet 3特性来启动应用,让我们详细的看一下:

1、spring是怎么启动的?
spring支持原始的web.xml来启动应用也支持最新的servlet3+的方式
让我们看看web.xml方式的处理步骤:
1.servlet 容器读取web.xml
2.定义在web.xml里面的DispatcherServlet被容器实例化
3.DispatcherServlet读取WEB-INF/{servletName}-servlet.xml来创建WebApplicationContext 
4.最终DispatcherServlet把bean注册到application context里面

再来看看使用servlet3+方式的处理步骤:
1.容器查找实现了ServletContainerInitializer 的类并进行执行
2.SpringServletContainerInitializer找到所有实现了WebApplicationInitializer接口的类
3.WebApplicationInitializer使用XML或者@Configuration标注的类来创建context
4.WebApplicationInitializer使用先前创建好的context创建DispatcherServlet 

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使用main方法作为入口来拉起嵌入的web 服务器。并且把application context的Servlet, Filter,和ServletContextInitializer bean与嵌入的servlet容器绑定起来

另外一个特性是spring boot会自动扫描main方法所在类的相同包路径或者子包路径里面的component
spring boot也提供了通过war包的方式部署在外部的容器里面,这这种情况下,我们必须继承SpringBootServletInitializer:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    // ...
}

这里外部的servlet容器查找war包中META-INF文件里面定义的main-class,SpringBootServletInitializer 将会绑定Servlet, Filter,和ServletContextInitializer.

八、打包和部署
最后,让我们看看应用是如何打包和部署的。二者都支持通用的打包管理技术比如maven和gradle.但是当部署的时候,二者会有许多不同
例如: Spring Boot Maven Plugin提供了spring boot在maven的支持,它也可以打包成可执行的jar或者war,并且能立即运行应用
与Spring相比,Spring Boot在部署方面的一些优势包括:
提供嵌入式的容器支持
提供使用java -jar命令来独立的运行jar
当部署在外部容器时,可以选择排除依赖来避免潜在的jar冲突
当部署的时候,可以激活特定的配置文件
集成测试的时候可以随机生成端口号

九、结论
这这篇文档中,我们学习了spring和spring boot的不同
简单一句话:我们可以这样说 spring boot简化和扩展了spring,让我们的开发、测试和部署更方便

你可能感兴趣的:(spring,spring,boot,servlet3)