I worked on a core Spring Boot project for five or six years at a very large enterprise. In my opinion, the most dangerous thing about this framework is that it makes its core users feel far too self-assured.
When looking at problems, your mind becomes consumed with how to force everything into design patterns—like architectural separation, DI, or interface / implementation split. This causes developers to lose sight of the actual essence of the problem because they are obsessed with conforming to the framework.
Because the ecosystem and toolchain surrounding Spring Boot and Java are so mature and well-supported, it is very easy to find community tools that make you feel like you are doing things the "right way."
I only realized these issues after I left Spring Boot and Java development behind. Now, I much prefer using TypeScript or Python to write code (for example, web servers).
I also prefer using various SaaS solutions to handle authentication and user registration rather than rebuilding it all myself with Spring Boot Security. I honestly never want to go back to the days of writing Java again.
Funny how that works - I started with Spring both before and after Boot as well as some Scala.
I wouldn’t trade Java / Spring for the world. It forces a coherence, perhaps not perfectly, but it provides guidelines to follow.
I’ve been stuck in Node / TypeScript / Microservice hell for most of the last 15 years and I couldn’t hate it more. The open-source ecosystem is extremely lacking, even now, on something like a good XML library. I think we’ve got four different ones installed in our core platform each handling different needs (traversal, generation, manipulation, validation).
On top of it all, since there isn’t “one way” we’ve got several dozen micro services. There isn’t a single bit of consistency other than “Express.” Logging, authentication, routing, validation - it’s all completely up in the air. It robs us all of efficiency from the lack of common language and pattern. We spend more time refreshing ourselves on any given project than doing feature work or bug fixes.
Spring is such a massive framework and it definitely has parts that aren't, frankly, well done. More than once Spring has ultimately been the source of performance issues for us with the solution being to ditch spring and do things with just the JDK. A lot of those cases have been fixed, however, even in the best case spring will take something that could have been a single function call and turn it into a maze of 20 different function calls because it's handling all sorts of weird edge and corner cases that aren't applicable to your code. It also doesn't help that some things are simply bolted in which makes it even harder to understand what is going on under the covers.
It also doesn't help that it's really easy to end up bringing in the entire framework for what you assumed were single function portions of the framework.
That said, it's the framework you probably want to use if you are doing Java. Just not if you are doing fast java.
I like Java fine. I would probably prefer Ruby, Rust or LISP given the chance. But I can't disagree with anything you say. So many Java enterprise shops have absurd inheritance and "design pattern" abuse that makes it harder to actually work with the code, and slows things down.
Ops person here who has supported Java/SpringBoot applications. I think most of dislike of Java apps comes not from language or framework BUT from fact that most Java using workspaces are filled with mediocracy. They tend to be businesses with products that have extreme moats and thus quality of software barely matters. I imagine most people who would even read this medium article are dreaming of better than that.
Alternatively, I think of Java and Spring Boots as being incredibly valuable by letting companies that don't really have software as a core competency to make reasonably performant and structured applications.
Mediocrity will never not exist, and you unlock a lot of value by optimising for it.
I 100% agree. I have seen enterprise spring applications that throw away all of the speed through huge amounts of hot path object creation, nested loops, absurd amounts of factories, etc. After going through enough AbstractFactoryFactory calls to make object in an n^3 loop, the framework doesn't matter.
Usually languages are not the issue. It is the code that we write. As long as languages help us to find/debug a problem caused by crappy code - we should be good. Coding is kinda creative work. There is no standard to measure creativity or pitfalls of using wrong patterns. The incidents & RCAs usually find these. But most of the times it is already too late to fix core problem.
it doesn't mean that usage of something being very high is a clever idea.
lots of people take meth - so are you gonna take meth too.
```@EnableConfigurationProperties(CasConfigurationProperties.class)
@EnableScheduling
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.SimpleMFA)
@AutoConfiguration
@Import({
CasSimpleMultifactorAuthenticationComponentSerializationConfiguration.class,
CasSimpleMultifactorAuthenticationConfiguration.class,
CasSimpleMultifactorAuthenticationEventExecutionPlanConfiguration.class,
CasSimpleMultifactorAuthenticationMultifactorProviderBypassConfiguration.class,
CasSimpleMultifactorAuthenticationRestConfiguration.class,
CasSimpleMultifactorAuthenticationTicketCatalogConfiguration.class,
CasSimpleMultifactorAuthenticationWebflowConfiguration.class
})
public class CasSimpleMultifactorAuthenticationAutoConfiguration {
}```
this is what we mean by "JavaCulture" - java | JVM really wonderful things but the culture is what sets these things back
someone can't just go in and understand things - they have to understand a bunch of notations too.
then if you work at a place and try do things differently the same people will tell you to revise your PR cz it ain't software engineering (or it won't scale)
Huh, Enterprise usage of Blackberry was very very high and then it was not. And at one point SOA, SOAP/WSDL/XML usage was very very high and now I am told in my very enterprise job I'd be fired if I dared bring those names up.
Usage being high doesn't say anything about quality or suitability of a product specially in enterprise settings.
Im comparing against node equivalent ORMs and find spring consistently better. Yeah ive got to read up on annotations - but when it comes to transactions its always worth revisiting them to check for changes
Does this app take 5 minutes to start? That's so much dynamic Spring magic. Also, how do you keep track of control flow when anything at anytime could have been overridden by something else? It seems like tracing and debugging this thing would be like exploring someone else's codebase every time.
The class loading magic means you need to be exceptionally careful about things that would otherwise be very innocuous. It’s the rule, not the exception - that your average spring boot app will be doing tons of expensive stuff at startup. Most of which is unnecessary and was not even intended.
The JVM doesn’t need this kind of thing either, and it gets a bad wrap from the J(2)EE days, and the “simple” replacement that Spring was supposed to be.
No doubt there’s some benefits to be had, but I don’t think the trade-offs are worth it, especially at larger scales.
Just rewrote it in Go. Now we are using a server which consumes 30% of ram what the existing one used to and the latency and throughput have all improved.
Don't use these stupid java backend like sprinboot.
I wouldn’t reduce it to don't use Java/Spring Boot. Rewrites often (not always) look great because they remove years of accumulated complexity, not because the original stack was inherently bad.
Just rewrite it in X doesn't "just work" for complex systems. It ignores risk, and the fact that design usually matters more than language.
usually what you say is correct. but in case of entreprise java, just look at the article. you have no way of knowing or controlling which essential class your application will be running because some intern merged a similarly named class two hundred levels down in the codebase and now that is handling all your db queries. and it's not a bug but a highly praised feature.
it's useless abstractions for the sake of useless abstractions.
java was designed so that american architecs could write a few interfaces and cheap workforce overseas could implement the actual code.
and the EE stuff evolved in a way that features could be shipped just by adding a new component that would inject itself in the right places. java "engineers" have no idea how http or cookies work, but they know where to load the spring-auth bean in a 2mb maven config.
so, any rewrite from java is an exception to the rewrites are only good because you cleaned up old features rule.
When looking at problems, your mind becomes consumed with how to force everything into design patterns—like architectural separation, DI, or interface / implementation split. This causes developers to lose sight of the actual essence of the problem because they are obsessed with conforming to the framework.
Because the ecosystem and toolchain surrounding Spring Boot and Java are so mature and well-supported, it is very easy to find community tools that make you feel like you are doing things the "right way."
I only realized these issues after I left Spring Boot and Java development behind. Now, I much prefer using TypeScript or Python to write code (for example, web servers).
I also prefer using various SaaS solutions to handle authentication and user registration rather than rebuilding it all myself with Spring Boot Security. I honestly never want to go back to the days of writing Java again.
I wouldn’t trade Java / Spring for the world. It forces a coherence, perhaps not perfectly, but it provides guidelines to follow.
I’ve been stuck in Node / TypeScript / Microservice hell for most of the last 15 years and I couldn’t hate it more. The open-source ecosystem is extremely lacking, even now, on something like a good XML library. I think we’ve got four different ones installed in our core platform each handling different needs (traversal, generation, manipulation, validation).
On top of it all, since there isn’t “one way” we’ve got several dozen micro services. There isn’t a single bit of consistency other than “Express.” Logging, authentication, routing, validation - it’s all completely up in the air. It robs us all of efficiency from the lack of common language and pattern. We spend more time refreshing ourselves on any given project than doing feature work or bug fixes.
Madness!
It also doesn't help that it's really easy to end up bringing in the entire framework for what you assumed were single function portions of the framework.
That said, it's the framework you probably want to use if you are doing Java. Just not if you are doing fast java.
Mediocrity will never not exist, and you unlock a lot of value by optimising for it.
I expected to see some new Spring 'tricks' in this post, but it's pretty much regular things that people might do in larger codebases.
lots of people take meth - so are you gonna take meth too.
```@EnableConfigurationProperties(CasConfigurationProperties.class) @EnableScheduling @ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.SimpleMFA) @AutoConfiguration @Import({ CasSimpleMultifactorAuthenticationComponentSerializationConfiguration.class, CasSimpleMultifactorAuthenticationConfiguration.class, CasSimpleMultifactorAuthenticationEventExecutionPlanConfiguration.class, CasSimpleMultifactorAuthenticationMultifactorProviderBypassConfiguration.class, CasSimpleMultifactorAuthenticationRestConfiguration.class, CasSimpleMultifactorAuthenticationTicketCatalogConfiguration.class, CasSimpleMultifactorAuthenticationWebflowConfiguration.class }) public class CasSimpleMultifactorAuthenticationAutoConfiguration { }```
this is what we mean by "JavaCulture" - java | JVM really wonderful things but the culture is what sets these things back
someone can't just go in and understand things - they have to understand a bunch of notations too.
then if you work at a place and try do things differently the same people will tell you to revise your PR cz it ain't software engineering (or it won't scale)
Usage being high doesn't say anything about quality or suitability of a product specially in enterprise settings.
Now read up on all the dozen of annotations. But yeah, we did not want to "re-invent the wheel".
The JVM doesn’t need this kind of thing either, and it gets a bad wrap from the J(2)EE days, and the “simple” replacement that Spring was supposed to be.
No doubt there’s some benefits to be had, but I don’t think the trade-offs are worth it, especially at larger scales.
Just rewrote it in Go. Now we are using a server which consumes 30% of ram what the existing one used to and the latency and throughput have all improved.
Don't use these stupid java backend like sprinboot.
Just rewrite it in X doesn't "just work" for complex systems. It ignores risk, and the fact that design usually matters more than language.
it's useless abstractions for the sake of useless abstractions.
java was designed so that american architecs could write a few interfaces and cheap workforce overseas could implement the actual code.
and the EE stuff evolved in a way that features could be shipped just by adding a new component that would inject itself in the right places. java "engineers" have no idea how http or cookies work, but they know where to load the spring-auth bean in a 2mb maven config.
so, any rewrite from java is an exception to the rewrites are only good because you cleaned up old features rule.