The over-engineering in the Java ecosystem has wasted more of my time than saved it.
Having worked with Spring for years (and still working with it, unfortunately), I have found exactly the opposite.
It does way too much dynamically, making debugging hard and rendering the type-system almost useless.
Sure, it comes with a lot of libraries for handling a large varieties of tasks, but they all seem to be half-assed, and much of the time I either have to work around their limitations or write something myself anyway.
I really don't see why the same thing couldn't have been achieved by writing a bunch of useful libraries that don't depend on a dependency injection framework (which I also don't find much value in).
Finally, it takes forever to startup, making testing a pain. It even means that JUnit tests are slow.
That over-engineering is what save us from clunky solutions that are good for hello world applications and HN like posts, but fail when doing deployments across heterogeneous platforms on Fortune 500 IT departments with endless number of external contractors and technology stacks hardly seen elsewhere.
And if I have to pick between managing WebSphere containers and taking care of k8s, I will rather pick WebSphere.
As such, I'd describe it as a good combination of highly dynamic architecture with lots of manual control. Of course, all of this is enabled with copious amounts of magic, which is usually why people don't like Spring.