A Comparison Between Spring and Spring Boot

本文详细比较了标准Spring框架与Spring Boot在MVC、Security模块的应用差异,SpringBoot通过简化配置和自动功能实现,加速了开发过程。SpringBoot依赖自动配置,只需web starter,而Spring需手动配置更多。

A Comparison Between Spring and Spring Boot

by baeldung


1. Overview

In this write-up, we're going to look at the differences between the standard Spring frameworks

and Spring Boot.

We'll focus on and discuss how the modules of Spring, like MVC and Security, differ when used in core Spring versus when used with Boot.

2. What Is Spring?

Simply put, the Spring framework provides comprehensive infrastructure support for developing Java applications.

It's packed with some nice features like Dependency Injection and out of the box modules like:

Spring JDBC
Spring MVC
Spring Security
Spring AOP
Spring ORM
Spring Test

These modules can drastically reduce the development time of an application.

For example, in the early days of Java web development, we needed to write a lot of boilerplate code to insert a record into a data source. But by using the JDBCTemplate of the Spring JDBC module we can reduce it to a few lines of code with only a few configurations.

3. What Is Spring Boot?

Spring Boot is basically an extension of the Spring framework which eliminated the boilerplate configurations required for setting up a Spring application.

It takes an opinionated view of the Spring platform which paved the way for a faster and more efficient development eco-system.

Here are just a few of the features in Spring Boot:

  • Opinionated ‘starter' dependencies to simplify build and application configuration
  • Embedded server to avoid complexity in application deployment
  • Metrics, Health check, and externalized configuration
  • Automatic config for Spring functionality – whenever possible

Let's get familiar with both of these frameworks step by step.

4. Maven Dependencies

First of all, let's look at the minimum dependencies required to create a web application using Spring:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

Unlike Spring, Spring Boot requires only one dependency to get a web application up and running:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

All other dependencies are added automatically to the final archive during build time.

Another good example is testing libraries. We usually use the set of Spring Test, JUnit, Hamcrest, and Mockito libraries. In a Spring project, we should add all these libraries as dependencies.

But in Spring Boot, we only need the starter dependency for testing to automatically include these libraries.

Spring Boot provides a number of starter dependencies for different Spring modules. Some of the most commonly used ones are:

spring-boot-starter-data-jpa
spring-boot-starter-security
spring-boot-starter-test
spring-boot-starter-web
spring-boot-starter-thymeleaf

For the full list of starters, also check out the Spring documentation.

5. MVC Configuration

Let's explore the configuration required to create a JSP web application using both Spring and Spring Boot.

Spring requires defining the dispatcher servlet, mappings, and other supporting configurations. We can do this using either the web.xml file or an Initializer class:

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("/");
    }
}

We also need to add the @EnableWebMvc annotation to a @Configuration class and define a view-resolver to resolve the views returned from the controllers:

@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;
   }
}

By comparison to all this, Spring Boot only needs a couple of properties to make things work, once we've added the web starter:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

All the Spring configuration above is automatically included by adding the Boot web starter, through a process called auto-configuration.

What this means is that Spring Boot will look at the dependencies, properties, and beans that exist in the application and enable configuration based on these.

Of course, if we want to add our own custom configuration, then the Spring Boot auto-configuration will back away.

5.1. Configuring Template Engine

Let's now learn how to configure a Thymeleaf template engine in both Spring and Spring Boot.

In Spring we need to add the thymeleaf-spring5 dependency and some configurations for the view resolver:

@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 required only the dependency of spring-boot-starter-thymeleaf to enable Thymeleaf support in a web application. But because of the new features in Thymeleaf3.0, we have to add thymeleaf-layout-dialect also as a dependency in a Spring Boot 2 web application. Alternatively, we can choose to add a spring-boot-starter-thymeleaf dependency that'll take care of all this for us.

Once the dependencies are in place, we can add the templates to the src/main/resources/templates folder and the Spring Boot will display them automatically.

6. Spring Security Configuration

For the sake of simplicity, we'll see how the default HTTP Basic authentication is enabled using these frameworks.

Let's start by looking at the dependencies and configuration we need to enable Security using Spring.

Spring requires both the standard spring-security-web and spring-security-config dependencies to set up Security in an application.

Next, we need to add a class that extends the WebSecurityConfigurerAdapter and makes use of the @EnableWebSecurity annotation:

@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();
    }
}

Here we're using inMemoryAuthentication to set up the authentication.

Similarly, Spring Boot also requires these dependencies to make it work. But we need to define only the dependency of spring-boot-starter-security as this will automatically add all the relevant dependencies to the classpath.

The security configuration in Spring Boot is the same as the one above.

If you need to know how the JPA configuration can be achieved in both Spring and Spring Boot, then check out our article A Guide to JPA with Spring.

7. Application Bootstrap

The basic difference in bootstrapping of an application in Spring and Spring Boot lies with the servlet. Spring uses either the web.xml or SpringServletContainerInitializer as its bootstrap entry point.

On the other hand, Spring Boot uses only Servlet 3 features to bootstrap an application. Let's talk about this in detail.

7.1. How Spring Bootstraps?
Spring supports both the legacy web.xml way of bootstrapping as well as the latest Servlet 3+ method.

Let's see the web.xml approach in steps:

Servlet container (the server) reads web.xml
The DispatcherServlet defined in the web.xml is instantiated by the container
DispatcherServlet creates WebApplicationContext by reading WEB-INF/{servletName}-servlet.xml
Finally, the DispatcherServlet registers the beans defined in the application context
Here's how Spring bootstraps using Servlet 3+ approach:

The container searches for classes implementing ServletContainerInitializer and executes
The SpringServletContainerInitializer finds all classes implementing WebApplicationInitializer
The WebApplicationInitializer creates the context with XML or @Configuration classes
The WebApplicationInitializer creates the DispatcherServlet with the previously created context.

7.2. How Spring Boot Bootstraps?

The entry point of a Spring Boot application is the class which is annotated with @SpringBootApplication:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

By default, Spring Boot uses an embedded container to run the application. In this case, Spring Boot uses the public static void main entry-point to launch an embedded web server.

Also, it takes care of the binding of the Servlet, Filter, and ServletContextInitializer beans from the application context to the embedded servlet container.

Another feature of Spring Boot is that it automatically scans all the classes in the same package or sub packages of the Main-class for components.

Spring Boot provides the option of deploying it as a web archive in an external container as well. In this case, we have to extend the SpringBootServletInitializer:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    // ...
}

Here the external servlet container looks for the Main-class defined in the META-INF file of the web archive and the SpringBootServletInitializer will take care of binding the Servlet, Filter, and ServletContextInitializer.

8. Packaging and Deployment

Finally, let's see how an application can be packaged and deployed. Both of these frameworks support the common package managing technologies like Maven and Gradle. But when it comes to deployment, these frameworks differ a lot.

For instance, the Spring Boot Maven Plugin provides Spring Boot support in Maven. It also allows packaging executable jar or war archives and running an application “in-place”.

Some of the advantages of Spring Boot over Spring in the context of deployment include:

  • Provides embedded container support
  • Provision to run the jars independently using the command java -jar
  • Option to exclude dependencies to avoid potential jar conflicts when deploying in an external container
  • Option to specify active profiles when deploying
  • Random port generation for integration tests

9. Conclusion

In this tutorial, we've learned about the differences between Spring and Spring Boot.

In a few words, we can say that Spring Boot is simply an extension of Spring itself to make development, testing, and deployment more convenient.

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
<think>好的,用户现在遇到了“comparisonbetween pointerand integer”的编译错误或警告,需要我帮忙解决。首先,我得回忆一下C/C++中这个错误的常见原因。通常,这种错误是因为在比较操作中,一个操作数是指针,另一个是整数,而两者类型不兼容导致的。接下来,我需要结合用户提供的引用内容。引用[1]提到的是将算术表达式转换为指针时可能出现的截断问题,这可能与指针和整数的比较有关联。引用[2]的代码示例虽然涉及C++的Ranges库,但可能用户之前的问题涉及管道操作,不过目前的问题可能不太相关。引用[3]讨论了返回std::ostream时不能按值返回,这可能与运算符重载有关,但用户现在的问题更基础。 用户之前的问题是关于多字符常量的引用方式,现在转向指针和整数的比较错误,可能需要检查用户是否错误地使用了单引号或双引号,导致类型不匹配。例如,将字符常量(整数)与字符串(指针)比较,比如'A'和 "A",这会导致指针与整数的比较。接下来,我需要分步骤分析错误原因。首先,常见的情况是比较字符和字符串,比如if(c== "A"),这里c是char类型,"A"是constchar*,导致比较指针和整数。另一个情况可能是将数组名(退化为指针)与整数比较,比如arr ==0,而实际上应该检查arr是否为NULL,但数组名不能这样比较。 然后,解决方案部分需要指出如何正确使用单引号,或者检查变量声明是否正确。例如,使用字符常量时用单引号,字符串用双引号。同时,检查变量是否是误声明为指针,比如char*c= 'A';这样的错误会导致类型不匹配。另外,用户提供的引用[1]中的问题可能涉及到将整数转换为指针时的截断,比如(int*)123这样的强制转换,但如果在比较中误将指针和整数比较,也会触发类似的错误。需要提醒用户注意强制转换的正确性,以及类型是否匹配。可能还需要提到函数返回指针的情况,比如误将返回的指针与整数比较,或者反之。例如,strcmp返回的是整数,如果用户误用==0来比较字符串内容,但实际应该使用strcmp的结果是否为0,而不是直接比较指针。 最后,总结常见的错误场景,并提供修改示例,帮助用户理解如何修正代码。同时,生成相关问题,帮助用户深入理解指针和整数类型的区别,避免类似错误。</think>### 关于 "comparison between pointer and integer" 错误的解决方案 在 C/C++ 中,**指针与整数的直接比较**是类型不兼容的典型错误[^1]。以下是常见原因与修复方法: --- #### 错误场景分析 1. **字符与字符串混淆** ```c char c = 'A'; if (c == "A") { /* 错误:char 与 char* 比较 */ } ``` - **原因**:`"A"` 是字符串常量(类型为 `const char*`),而 `c` 是字符(类型为 `char`) - **修复**:改用字符常量 `'A'` ```c if (c == 'A') // 正确 ``` 2. **数组名与整数比较** ```c int arr[5]; if (arr == 0) { /* 错误:数组名退化为指针 */ } ``` - **原因**:`arr` 退化为指针(类型为 `int*`),不能直接与整数 `0` 比较 - **修复**:检查指针是否为空 ```c if (arr == NULL) // 正确(仅当 arr 是动态分配时) ``` 3. **函数返回类型错误** ```cpp const char* get_str() { return "hello"; } int main() { if (get_str() == 0) { /* 错误:指针与整数比较 */ } } ``` - **修复**:检查指针是否为 `nullptr`(C++)或 `NULL`(C) ```cpp if (get_str() == nullptr) // C++ ``` --- #### 通用修复策略 1. **明确类型标识** - 使用 `char` 时确保单引号 `' '` - 使用字符串时确保双引号 `" "` - 指针类型变量命名建议以 `p` 开头(如 `pValue`) 2. **强制类型转换验证** ```c int* p = (int*)0x1234; // 显式指针转换 if (p == (int*)0x1234) { /* 合法比较 */ } ``` 3. **编译器选项检查** - 启用严格类型检查(如 GCC 的 `-Wall -Werror`) --- #### 代码示例对比 ```c // 错误示例 const char* str = "test"; if (str[0] == "t") { /* 错误:char 与 char* 比较 */ } // 正确示例 if (str[0] == 't') { /* 正确 */ } ``` --- ### 关键区别总结 | 类型 | 存储内容 | 比较操作符使用场景 | |-----------|----------------|---------------------------| | 整数 | 直接数值 | `==`, `!=`, `<`, `>` | | 指针 | 内存地址 | 仅限 `==`, `!=`(地址比较)| ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员光剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值