Skip to main content
  1. Blog Posts/

When Spring Comes

·6 mins· loading · loading · ·
Table of Contents

I probably should have said this earlier, but I’m excited to say that live in Japan now! And as I’m writing this, it’s March 20, 2026, which means it’s Vernal Equinox Day here, or Shunbun no Hi (春分の日), the public holiday that marks the arrival of spring. So yes, the title is a little on the nose. But honestly, I couldn’t resist.hmm w

There is something weirdly fitting about writing about Spring on the day spring officially begins, because Spring Boot has always felt a bit like that season change in Java backend. Not in the cheesy “flowers are blooming” sense, but in the more practical sense that a whole environment suddenly got easier to live in. Things that used to feel cold, rigid, and unnecessarily punishing started loosening up.

If all you know is modern Java backend, Spring Boot can look almost suspiciously clean. You pull in a starter, write a main class, throw on a few annotations, and somehow you already have a web app, dependency injection, configuration, health checks, and an embedded server behaving themselves in one neat little package. It is polished enough that it can hide the mess that came before it.

But Java backend did not start here.

Before Boot, there was Spring. Before Spring, there was J2EE. And before anyone started praising Java for its mature backend tooling, a lot of people were quietly suffering through XML jungles, heavyweight application servers, and enough deployment ceremony to make a simple web app feel like a government process. Spring Boot did not appear out of nowhere. It was the result of years of friction slowly being shaved down.

That is what makes its history worth looking at. Spring Boot was not just another framework release. It was the point where a whole ecosystem finally admitted that getting started had become too hard, and that a lot of backend work was being wasted on setup nobody actually enjoyed. So since spring has quite literally just started outside my window, this feels like as good a time as any to go back and look at how Spring came to Java in the first place, and how Boot changed the season after that.

The Winter of J2EE
#

If you go back to the early enterprise Java years, the stack looked very different. J2EE was the dominant model, and with it came the full package: servlets, JSPs, EJBs, WAR files, and application servers like WebLogic, WebSphere, and JBoss. This approach was powerful, sure, but it also came with a very specific kind of misery. You were not just writing business logic. You were negotiating with infrastructure at every step.

The pain showed up in predictable ways. Configuration was everywhere, and most of it lived in verbose XML. Database connections, transactions, messaging, web settings, security, deployment descriptors, all of it wanted another file, another tag, another layer of ceremony. Components were often tightly coupled to their environment, which made testing awkward and swapping things out even more awkward. And then there was feature bloat: large application servers shipped with every enterprise feature under the sun whether you needed it or not, which meant even a relatively simple app could end up dragging a huge amount of weight behind it.

That era left a mark on how people talked about Java. The language itself was not the problem. The problem was everything that accumulated around it. Enterprise Java developed a reputation for being serious, but also for being heavy, over-configured, and hard to love. You could absolutely build large systems with it. People did. But nobody sane would call the experience elegant.

This is the world Spring walked into.

Spring Blooms
#

The official Spring docs put the origin plainly:

“Spring came into being in 2003 as a response to the complexity of the early J2EE specifications.”

Spring Framework Overview

That sentence is doing a lot of work. Spring was not created because someone wanted to invent a new religion for Java. It was created because existing enterprise Java had become too cumbersome, and enough people were hungry for something lighter. Rod Johnson’s critique of J2EE, especially the idea that you could build enterprise software around plain old Java objects instead of giant container-driven abstractions, landed at exactly the right time.

The early promise of Spring was refreshingly practical. Instead of forcing developers to surrender to a heavyweight platform, it gave them an inversion of control container that could manage object wiring more cleanly. Instead of making everything revolve around specialized enterprise components, it allowed ordinary Java classes to do ordinary Java things. Instead of one giant all-or-nothing stack, it offered modularity. You could use the parts you needed and ignore the parts you did not.

Spring’s own design philosophy captured that shift:

“Provide choice at every level.”

Spring Framework Overview

That sounds tame now because Spring ended up becoming the establishment. Back then, it felt like a breath of fresh air. Dependency injection reduced hard-coded wiring. The framework wrapped common enterprise concerns without forcing everything through the same old J2EE bottlenecks. Data access got less painful. Web MVC became more approachable. Testing became more realistic. Spring did not eliminate configuration overnight, but it made the whole experience feel far more humane.

That is why Spring spread so aggressively through the Java world in the 2000s. It solved a real problem, and it solved it in a way that made developers feel like the framework was working with them rather than standing over them with a clipboard.

The Road to Spring Boot
#

Of course, success changes a framework.

As Spring kept growing, it became the default answer to more and more backend problems. That was good for the ecosystem, but it also created a new kind of friction. A typical Spring application stopped looking like one clean module and started looking like a carefully assembled machine: Spring Core, Spring MVC, Spring Data, security, messaging, validation, database drivers, logging, templating, build plugins, and a long trail of version compatibility concerns behind all of them.

The old J2EE winter was gone, but Spring had developed its own sort of climate. It was far more pleasant than what came before, yet it still asked for a lot of assembly. You still had to collect the right dependencies, keep the versions aligned, write configuration, decide how the application would be packaged, and wire together the shape of the project before you could get to the part you actually cared about. If you were experienced, this was manageable. If you were new, it was intimidating. If you were on a team spinning up services repeatedly, it was repetitive in the worst way.

This was the second big shift in the story. The pain had moved. Developers were no longer asking how to escape the worst parts of J2EE. They were asking why even the better answer still involved so much bootstrapping overhead.

And around the same time, the industry itself was moving. The broader web world had already been drifting toward faster setup, stronger conventions, and lighter deployment models. Frameworks like Ruby on Rails had made “convention over configuration” feel normal. In the Java ecosystem, newer approaches were showing that embedded servers and self-contained apps could make development a lot smoother. The expectation was changing. Developers wanted to get an application running quickly. They wanted less ceremony up front. They wanted the platform to make the obvious decisions for them unless they explicitly opted out.

Spring was too important not to respond to that.

When Spring Boot Sprouted
#

One of the clearer public signs of this shift showed up in 2012, in a GitHub issue titled Improved support for “containerless” web application architectures. The argument was straightforward: if a Spring web app could bootstrap from a simple main() method and run with an embedded server, a lot of the old deployment and configuration pain would simply disappear.

The issue framed the problem in a way that still sounds familiar:

“a servlet container comes with [a] learning curve… I think Spring’s web application architecture can be significantly simplified… by embedding and unifying the configuration of those common web container services within a Spring container bootstrapped from a simple main() method.”

spring-projects/spring-framework issue #7079

That idea ended up mattering a lot. It pointed directly at one of the biggest remaining bits of friction in the Java web stack: the assumption that your application needed to be packaged as a WAR and deployed into an external container before it could really live.

Then came the more decisive moment. In 2013, Phil Webb replied on that same issue with what was basically the public birth announcement of Spring Boot:

“Rather than fix this as part of the core Spring Framework we have decided to start a new project called Spring Boot that addresses this and a number of other issues.”

spring-projects/spring-framework issue #7079

That decision was smart for two reasons. First, it acknowledged that this was not just a small patch to Spring Framework. It was a broader attempt to reshape the startup experience. Second, it gave the team room to move quickly without being chained to all the compatibility constraints of the core framework.

Soon after, the Spring team laid out Spring Boot’s purpose in even more direct terms:

“To provide a radically faster and widely accessible ‘getting started’ experience for all Spring development”

Spring Boot: Simplifying Spring for Everyone

That was the mission. Not to replace Spring. Not to fork it into a separate universe. To make getting started dramatically easier.

What Spring Boot Brought to the Table
#

Spring Boot’s biggest contribution was not some single technical trick. It was the way a handful of ideas came together into a much smoother developer experience.

The first was starter dependencies. Instead of manually assembling half the world in your build file, Boot gave you curated dependency bundles for common use cases. Want a web app? Pull in spring-boot-starter-web and you get Spring MVC, JSON support, validation, logging defaults, and an embedded servlet container without playing dependency bingo by hand.

The second was auto-configuration. Boot looked at what was on the classpath and made sensible decisions based on what it found. If the usual ingredients for a web service were present, it wired the obvious pieces together. If a database library was present, it could infer the sort of setup you probably needed. You could still override it, but the framework stopped forcing you to spell out every predictable step yourself.

The third was the embedded server model. This was one of the biggest psychological changes. Instead of thinking of your app as a WAR that needed to be dropped into an external container, Boot let the app be the thing you ran. Package it as a jar, run it, and the server comes with it. That sounds normal now. It was not always normal in Java land.

The fourth was production-ready defaults. Health checks, metrics, externalized configuration, environment-specific settings, all the stuff teams eventually need once an app leaves a laptop, became much easier to reach. Boot was not just solving hello-world problems. It was trying to make the common path from local dev to production less painful too.

And importantly, it did all of this without turning itself into a code generator or wizard machine:

“Spring Boot does not generate code or make edits to your files.”

Building an Application with Spring Boot

That line matters more than it looks. Spring Boot was not trying to hide the framework behind a disposable scaffold. It was still Spring underneath. The same container, the same programming model, the same ecosystem. Boot just supplied a much stronger set of defaults and a much shorter path to a working application.

Spring itself now describes Boot this way:

“Spring Boot provides a quick (and opinionated) way to create a production-ready Spring-based application.”

Spring Framework Overview

That word, opinionated, ended up being the whole game. Spring Boot won by being willing to make obvious decisions on your behalf until you had a reason to disagree.

The Microservice Moment
#

Timing helped too.

Spring Boot arrived just as the industry was moving hard toward smaller services, faster delivery cycles, and cloud-friendly deployment models. The old model of carefully tending a giant application server and deploying monolithic WAR files into it did not fit that moment very well. Teams wanted independently deployable services. They wanted things that could boot quickly, run in containers, and behave consistently across environments.

Boot fit that moment almost perfectly. A standalone application with an embedded server, strong defaults, and easy externalized config maps very neatly onto the way modern backend teams wanted to work. That is a big reason Boot became so closely associated with the microservices wave, even if microservices as an idea obviously did not begin with Spring.

More concretely, Boot changed the economics of starting a new service. Before, a new Java service often meant a bunch of setup work before anyone even touched the business problem. After Boot, the startup cost dropped hard. Teams could generate a project, pull in the right starter, write a controller, write a config file, and have something running very quickly. That does not sound glamorous, but it is exactly the kind of change that reshapes how teams behave over time.

This is also why Boot spread beyond just greenfield hobby projects. Large organizations adopted it because it standardized service shape, reduced boilerplate, and made onboarding easier. Juniors could get farther without immediately drowning in configuration. Experienced engineers could spend less time on repetitive scaffolding and more time on the parts of backend work that are actually hard: data modeling, integration boundaries, reliability, performance, scaling, and the operational weirdness that only shows up in production.

After the Bloom
#

None of this means Spring Boot made complexity disappear. It just moved it.

This is the part people eventually learn the hard way. Boot makes the happy path dramatically smoother, but if you stay in the ecosystem long enough you eventually hit the underside of the abstraction: a missing bean, confusing transaction behavior, an auto-configuration that kicked in when you did not want it to, some proxy weirdness, component scanning that missed something obvious, or a startup failure whose stack trace looks like it was written during a nervous breakdown.

That is not a contradiction. It is the cost of convenience. Spring Boot works because it compresses a lot of setup into framework decisions. When those decisions line up with what you want, life is good. When they do not, you need to understand what Boot is standing on top of. That is why the healthiest way to learn Boot is still to learn Spring. Dependency injection, bean lifecycles, configuration properties, auto-configuration conditions, the application context, those are the floorboards. Boot feels magical until you need to debug it. After that, it either becomes understandable or it becomes haunted.

Still, that tradeoff was worth making. The old model wasted too much developer energy on ceremony. Boot took a real chunk of that overhead off the critical path.

A New Season for Java Backends
#

What Spring Boot changed, in the end, was not just syntax or packaging. It changed the default expectations around Java backend development. It proved that Java did not have to mean slow setup, bloated deployment, and endless configuration before the real work could begin. It showed that a mature enterprise ecosystem could still reinvent its developer experience without throwing away the foundation that made it powerful in the first place.

That is why Spring and Spring Boot are best understood as one long story rather than two unrelated ones. Spring was the answer to the worst parts of early J2EE. Spring Boot was the answer to the parts of Spring that had started becoming too tedious on their own. One cleared the ground. The other made the path much shorter.

If Boot feels natural today, that is because a lot of pain got normalized before it ever showed up. Spring Boot only looks obvious in hindsight. At the time, it was a very specific correction to a very real problem: backend engineers were spending too much time assembling infrastructure just to get to the starting line.

I think that is why it was worth revisiting Spring’s past in the first place. Without Spring, and later Spring Boot, it is hard to imagine the web as we know it looking the way it does today. That might sound dramatic, but honestly, Spring carried an absurd amount of the modern web on its back. And like any long-running project, looking back at its history helps explain why certain decisions were made and why the framework evolved in the direction it did.

So part of this post was just me paying due respect to the GOATs who got the ecosystem this far. And nonetheless, this is probably not the last time I write about it. I will most likely write some more knowledge-heavy Spring Boot articles in the future. So stay tuned!

Sources
#

Spring Framework Overview thumbnail
Spring Framework Overview
Official Spring documentation on the framework's origins, design philosophy, and relationship to Spring Boot.
https://docs.spring.io/spring-framework/reference/overview.html
Spring Boot: Simplifying Spring for Everyone thumbnail
Spring Boot: Simplifying Spring for Everyone
Phil Webb's 2013 Spring blog post introducing Spring Boot and its original goals.
https://spring.io/blog/2013/08/06/spring-boot-simplifying-spring-for-everyone/
Spring Boot thumbnail
Spring Boot
Official Spring Boot project page describing starter dependencies, auto-configuration, and production-ready features.
https://spring.io/projects/spring-boot
Building an Application with Spring Boot thumbnail
Building an Application with Spring Boot
Official getting-started guide explaining the lightweight application model and Boot's non-codegen approach.
https://spring.io/guides/gs/spring-boot
Issue #7079: Containerless Web Apps thumbnail
Issue #7079: Containerless Web Apps
The 2012 GitHub discussion that helped crystallize the need for a simpler, embedded-server-friendly Spring application model.
https://github.com/spring-projects/spring-framework/issues/7079
Jevin Laudo
Author
Jevin Laudo
Backend engineer passionate about scalable systems, tech, and sharing what I learn.

Related