DEV Community

Leon Pennings
Leon Pennings

Posted on • Originally published at blog.leonpennings.com

Still Reaching for Spring? Then You Might Still Think Happy Meals Are Fine Dining.

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 @Transactional

  • SQL/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)