Spring vs Spring Boot
The Spring Framework and Spring Boot are often spoken of as one thing, but they solve different problems. The Framework is the powerful, flexible core that wires your beans together; Boot is an opinionated layer on top that removes the ceremony of configuring it. Understanding where one ends and the other begins makes everything else about Spring Boot click into place.
Two layers, not two competitors
Spring Boot does not replace the Spring Framework. It depends on it. Every Boot application is a Spring application underneath: the same ApplicationContext, the same dependency injection, the same @Transactional and AOP machinery. What Boot adds is automation around configuration, dependency management, and packaging.
Note: A useful mental model: the Spring Framework gives you the engine and the parts; Spring Boot is the factory that assembles a working car with sensible defaults and lets you swap parts when you need to.
The classic Spring experience
In a traditional Spring MVC application, you are responsible for wiring the infrastructure. You declare a DispatcherServlet, a view resolver, a DataSource, a transaction manager, and a component-scan base package, either in XML or in Java @Configuration classes.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.devcraftly.app")
public class WebConfig {
@Bean
public DataSource dataSource() {
var ds = new org.apache.commons.dbcp2.BasicDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/app");
ds.setUsername("root");
ds.setPassword("secret");
return ds;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource ds) {
var emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(ds);
emf.setPackagesToScan("com.devcraftly.app.entity");
// JPA vendor adapter, properties, etc...
return emf;
}
// transactionManager, viewResolver, messageConverters, and more
}
On top of this you maintain a web.xml (or a WebApplicationInitializer), pick exact library versions yourself, and deploy the resulting WAR to an external Tomcat or WildFly. It is explicit and controllable, but every project repeats the same hundreds of lines.
The Spring Boot experience
Boot collapses that setup into a single annotated class plus a starter dependency.
package com.devcraftly.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AppApplication {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
}
Add spring-boot-starter-web and spring-boot-starter-data-jpa, set a few properties, and the DispatcherServlet, JSON converters, connection pool (HikariCP), EntityManagerFactory, and transaction manager are all configured for you.
spring.datasource.url=jdbc:mysql://localhost:3306/app
spring.datasource.username=root
spring.datasource.password=secret
Auto-configuration
Boot inspects the classpath and your beans, then applies conditional configuration. Each piece is guarded by annotations like @ConditionalOnClass and @ConditionalOnMissingBean, so your explicit beans always override the defaults. See auto-configuration for the mechanics.
Starters
Starters are curated dependency bundles. spring-boot-starter-web brings Spring MVC, Jackson, validation, and embedded Tomcat in mutually compatible versions, managed by the Spring Boot BOM. You stop hand-picking JARs and version conflicts mostly vanish.
Embedded server
Boot ships an embedded servlet container, so your app becomes a runnable java -jar app.jar artifact instead of a WAR you deploy elsewhere. This is ideal for containers and cloud platforms. See running & packaging.
Opinionated defaults
Logging, JSON serialization, error handling, and connection pooling all arrive pre-configured with battle-tested defaults, every one of which is overridable via properties or beans.
Side-by-side comparison
| Concern | Spring Framework | Spring Boot |
|---|---|---|
| Configuration | Manual (XML or Java @Configuration) | Auto-configured, override as needed |
| Dependency versions | Hand-managed | Managed by starters + BOM |
| Web server | External (deploy a WAR) | Embedded, runnable JAR |
| Bootstrapping | DispatcherServlet, web.xml, scan setup | @SpringBootApplication |
| Boilerplate | High | Minimal |
| Production tooling | Add-on | Built-in (Actuator) |
| Build/run | Build WAR, deploy to server | mvn spring-boot:run / java -jar |
| Time to first endpoint | Hours | Minutes |
| Control / flexibility | Maximum, explicit | High, with smart defaults |
Tip: Everything you learn about the core container, AOP, and transactions in plain Spring still applies in Boot. Boot changes how it is configured, not what it does.
When does each fit?
Reach for Spring Boot for nearly all new applications: REST APIs, microservices, scheduled jobs, batch processes, and standalone services. The fast feedback loop and embedded server are a clear win, and you can always drop down to manual configuration where you genuinely need it.
Plain Spring Framework still appears in a few situations:
- Legacy applications deployed to a shared, externally managed application server.
- Embedding Spring’s
ApplicationContextinside a non-Boot host (for example a plugin in a larger product). - Highly specialized setups where Boot’s auto-configuration fights your requirements more than it helps.
Warning: Even when targeting an external server, you can still use Spring Boot and produce a deployable WAR. Choosing the bare framework purely “to avoid magic” usually costs more than the magic it removes.
A quick gut check
If you find yourself writing a DispatcherServlet bean, a connection pool by hand, or a persistence.xml, ask whether a starter already does it. In Boot, the answer is almost always yes, and the first application page shows just how little code it takes to get a working endpoint.