Spring is paradoxical.
It “solves” problems it created — and trained a generation of developers to understand Spring, not software engineering.
Dependency Injection everywhere (even when there’s 1 implementation).
Interfaces for everything (even when there’s 1 implementation).
Annotations as the new programming language.
And @Transactional as a magical forcefield masking the fact that no one understands what should actually be atomic.
JDBC? SQL? DB design? Transaction boundaries?
Most Spring shops never touch them directly — they let the framework decide.
The result: the classic Enterprise Java Happy Meal.
Dumb, anemic JPA entities
Procedural service classes with 10+ injected dependencies
DTO ↔ Entity mapping hell
Mock-infested tests
AOP/DI voodoo that “just works” until it really doesn’t
And just when the team finally stabilizes their mess?
Spring drops a new version.
The Yearly Upgrade Treadmill
Every 12–18 months, Spring releases:
A new major version
New baseline Java versions
New incompatible Boot starters
New deprecated annotations
New “recommended patterns” that contradict last year’s tutorials
New features that solve problems introduced by last year’s features
Your Happy Meal toy gets replaced — and your codebase gets indigestion.
Upgrading usually means:
Fixing broken starters
Reworking configuration
Updating build plugins
Patching test failures
Rewriting infra classes
Revalidating transactions
Refactoring away deprecated magic
It’s like paying a subscription fee to keep your cardboard lunch “fresh.”
And Then There Are the License Costs
Some companies go one step further and buy
Spring Enterprise / Tanzu / VMware Spring support contracts.
That means:
Five-figure yearly costs for support on a framework that introduced half the problems you're paying to fix
SLAs for issues that often trace back to… using Spring in the first place
“Enterprise updates” that arrive on the same treadmill cycle
Vendor lock-in so deep it makes your DI graph look flat
Spring is the only fast-food chain where you pay extra for napkins and for someone to explain how to unwrap the burger.
Meanwhile, In the Real-Domain Restaurant…
A domain-first, fundamentals-first system avoids nearly all of this:
No DI spaghetti → fewer classes to break during upgrades
No framework annotations in the core → upgrades don’t touch the domain
Light adapters → easy to replace
No AOP magic → no proxies to explode under load
Transaction boundaries explicit → not tied to
@TransactionalSQL/JDBC understanding → no guessing when debugging N+1 or locks
Plain Java → almost nothing to upgrade except your own logic
Most of the Spring “upgrade pain” simply… disappears.
Because the domain isn't fused to the framework.
The Happy Meal vs Real-Domain Meal
Lines of Code: 10–20× more vs minimal — Real Meal wins
Layers / Classes: 40+ vs 5–10 aggregates — Real Meal wins
Team Size: 10+ mid-level devs vs 2–3 domain experts — Real Meal wins
New Feature Cost: Rewrite 20 files + fix mocks vs tweak 1 aggregate — Real Meal wins
Maintenance / 10 years: 5–10× higher vs evolves naturally — Real Meal wins
The Happy Meal wins exactly one category: easy hiring. You can staff it with annotation-followers straight from bootcamps.
Why the Happy Meal Still Sells
Because it’s:
Fast
Familiar
Tutorial-friendly
Bootcamp-friendly
Annotation-friendly
And you can staff a Spring shop with developers who know how to cook only with microwaves.
Actual cooking — modeling, SQL, transaction reasoning — is no longer taught.
“But Spring Boot Makes Starting an App Easy!”
Sure. But so does… 50 lines of plain Java.
You don’t need auto-config, starter packs, DI graphs, or annotation magic to run a web server.
A plain main() with embedded Jetty is literally:
configure Jetty
add a handler/servlet
start
join
That’s it.
50 LOC, tops.
Explicit. Predictable. Understandable.
Upgrades whenever you feel like it.
The uncomfortable truth:
Spring Boot didn’t solve a hard problem — it solved the fact that an entire generation of developers never learned to start a server.
And that’s the recurring pattern:
Spring abstracts everything developers no longer learn:
HTTP bootstrapping
Dependency wiring
Transaction scoping
SQL + JDBC
Actual DB design
Concurrency boundaries
Performance tuning
Error management
Convenience? Yes.
But at the cost of architectural dependence, annual migration pain, and a codebase tied to a framework rather than to ideas.
Spring Boot is the Happy Meal toy:
shiny, squeaky, comforting.
A Jetty main method is the frying pan:
simple, direct, real cooking.
Stop Eating Cardboard
So here’s the uncomfortable truth: you don’t need Spring Boot to ship a service.
A simple public static void main that spins up Jetty in ~50 LOC already gives you:
an HTTP server
dependency injection through plain constructors
zero magic
zero YAML
zero “Spring Boot 3.4 requires Java 27.1-preview” upgrade nightmares
zero licensing fees
Spring isn’t a productivity framework—it’s a convenience wrapper around things you can easily wire up yourself once you actually know how your system works.
But that’s the real problem, isn’t it?
We’ve raised a generation of developers who know Spring annotations but not transactions, who can configure a datasource in YAML but couldn’t write a proper JDBC transaction boundary if their production database depended on it. Spring keeps handing out Happy Meals—and teams keep eating the toys while forgetting to learn how to cook.
And then every year, we all get dragged through another “Spring Boot upgrade season,” complete with broken starters, namespace changes, new auto-configurations, and increasingly enterprise-y licensing terms—all to keep using features that never should’ve required a framework in the first place.
If your domain is rich, your architecture intentional, and your engineers actually understand the fundamentals, you don’t need the Spring Happy Meal. A simple Jetty runner and well-designed code will get you farther, cheaper, and with a fraction of the maintenance burden.
Spring is a solution to a problem that Spring created—and you don’t have to play that game.
Trade the Happy Meal for a real meal.
Your codebase (and your future team) will thank you.
Top comments (0)