Hacker News new | ask | show | jobs
by jacques_chester 3158 days ago
I like Spring, I find it makes Java development pleasant, plus I have unfair access to the Spring team members by working for the same company. So I'll bite.

> Huge XML configuration files instead of code? Spring (mostly annotations now).

Spring 3, yes. Spring 4 and 5, no. XML has not been the blessed configuration approach for ~4 years.

> Stupid names like AbstractSingletonProxyFactoryBean? Spring.

Java is a language that has evolved enormously in expressiveness since Spring began, meaning heavyweight Go4 patterns were necessary early on to maintain a flexible substrate with a uniform interface serving very many use cases? Spring.

> That aside, on startup Spring will auto generate classes which really slows things down.

I believed this urban legend too.

Dave Syer, who is understandably interested in Spring criticism, has done more empirical investigation than anyone on this topic[0].

The tl;dr is that boot time is proportional to total classes loaded. That's all, that's it.

In-memory reflection operations are hilariously, stupidly, insanely faster than I/O. The JVM fetches and loads classes individually. So if you have a lot of classes, it takes a longer time to load.

The other thing to bear in mind is that Spring relies on this much less than it used to. As the language and JVM have evolved, so has Spring.

> The underling code is full of maps to control request lifecycle ... Not real names but the idea and number of steps is.

Are you talking about servlet filters? Because any web framework is going to have a few of these. Spring MVC adds a handful and all of them can be removed, replaced or added to. Spring Security adds a bunch and all of them can be removed, replaced or added to. But the defaults are chosen because of feedback, not just for the heck of it.

> Add on top of this JPA which is super easy but quickly breaks down to a lot of DB calls. JPA is great for people who don't want to learn SQL and simple CRUD apps but anything with any amount of data will quickly slow down to thousands of DB round trips.

In general, yes, I agree that JPA is a PITA. For a small to medium system I would try to avoid it where possible. For a sufficiently large codebase -- thousands of domain objects, dozens or hundreds of programmers -- it might be a necessary evil.

Mind you, if you want to see a world where the database goes from abused to outright mocked and ignored, pay a visit to Rails land. It drives me batty.

[0] https://github.com/dsyer/spring-boot-startup-bench, particularly https://github.com/dsyer/spring-boot-startup-bench/tree/mast...

3 comments

I will admit that spring has gotten a lot better recently, but it is still a mess (IMHO of course) and this "benchmark" seems to agree.

The biggest issue I have with spring isn't performance but is the huge internal state that is the basis of Spring's DI.

After a few versions you end up with code that depends on bean named 'Abd" to preform a task, but in the next version is renamed to "Abc" which fixes the typo, but makes all the documentation off. And the 3 other classes that also needed that task still look for it under the name "Abd". And then the next major version replaces this entire module and the bean name is now "Xyz". To me this IS spring programming. Googling the DI names and trying them one by until you get the desired run time functionality.

I've had apps in production with unused beans defined (It only had 1 function that only throw an exception and was never called) but had to be defined or something would break. Multiple team members wasted some free time trying to locate the code that was requiring that bean but nobody could ever figure it out. At some point everybody gave up, it was easier to just let it be.

Most developers have little to no idea what is actually going on inside their spring apps (or even what half their dependencies are). When a struts like vulnerability comes along in the spring world it is going to be a massive PITA to fix. With how complex this all is I have little doubt that a vulnerability exist somewhere in there.

The Struts vulnerability was less about Struts and more about the universal difficulty of dependency management.

Which Spring Boot ameliorates by providing starter POMs. Curated, levelled, updated collections of dependencies for common cases. No need to play whack-a-dep with Maven or Gradle. No need to track 50 different dependencies yourself.

The thing is: I don't care how Spring does the magic. I care that I don't have to care.

I came to Spring and Java-for-real development relatively late -- by fluke I was on what is almost certainly the first Boot production app ever deployed, back in early 2014.

Later I got a chance to see the primordial world of Spring 3. I understand the residual hate.

> Are you talking about servlet filters? Because any web framework is going to have a few of these. Spring MVC adds a handful and all of them can be removed, replaced or added to. Spring Security adds a bunch and all of them can be removed, replaced or added to. But the defaults are chosen because of feedback, not just for the heck of it.

Even ignoring filters, it seems to me that Spring brings a lot of overhead. Adding an annotation to a method sometimes means that would appear to be a direct call between two of your beans is in fact separated by 10 method calls on a stack trace. In many cases this is not an issue (expecially in "enterprise" applications), but it is clear to me that performance is not really one of the main concerns of spring developers.

> In-memory reflection operations are hilariously, stupidly, insanely faster than I/O. The JVM fetches and loads classes individually. So if you have a lot of classes, it takes a longer time to load.

One thing that I have noticed is that with all these annotation, the Java compiler is not doing much any more. Java has effectively became a dynamic language (as in an interpreted language) where errors are only visible at runtime when hitting some specific method.

Coupled with the really slow startup time (again, I talk about Spring Boot--I get a steady 10s vs 0.01s for Go, same functionality), it makes developing a simple CRUD a pain compared to both Go or Python/Ruby...

I've never seen IntelliJ or Eclipse fail to work out how to get to the definition I'm looking for.

For Ruby I see RubyMine doing what amounts to a fulltext search. It's next to useless.

For startup time, see my notes on the JVM and the link to Dave Syer's notes.

There's also the devtools starter to ease the JVM reload pain. Which to me is by far the biggest suckiness of the thing.