6 ms·
Sure, and eventually you end up rebuilding an [ad hoc, informally-specified, bug-ridden, slow] DI container because: * Static references become a tangled mess,
by stickfigure 5y ago
Sure, and eventually you end up rebuilding an [ad hoc, informally-specified, bug-ridden, slow] DI container because:
* Static references become a tangled mess, and you start wanting some structure around that.
* You have to answer "how does ABC component get access to DEF?" for increasingly difficult combinations of ABC and DEF.
Excepting Spring, pretty much all Java DI containers are lightweight.
- throwaway1492 5y agoThis, it’s really exhausting to read this never ending wheel reinvention. Sure any one can use simpler non-spring frameworks, and other “non standard” frameworks and libraries for 1/10 or 1/100 of the functionality, and get 10-100x the bugs and much less or zero support. But we need netty! And then when you add thread pools, jdbc, logging, etc? Yep you’ve reimplemented spring. Just use spring, spend the time to learn it and reap the rewards.
- wtetzner 5y agoAs someone who dealt with a ton of Spring in the recent past, I completely disagree. First of all, thread pools are part of the standard library. Spring adds little to no value on top of it. Second, reinventing some of that stuff is absolutely worthwhile, because Spring's library design/implementation is not very good. Finally, when I had the opportunity to start a new Java project, I opted to not use Spring. I finally had a server that started up fast, took less code than a Spring project, was easily navigable in an IDE, and whose code was generally easier to follow. It was also easier to write tests for. One thing I learned is that people seem to underestimate just how thin Spring's abstractions are over stuff in the library, servlets, etc. Most of what Spring does is wrap things in a bean interface so they can be used with DI (which is something I’ve never found any value in).
- geodel 5y agoWell you are missing one of the great feature of Spring framework: Converting compile time errors in to runtime exceptions. Jokes apart you are absolutely right about non-spring based services. I did same using plain Java + embedded tomcat for some services. No cargo-cult like endless decorative packages and classes. Exactly same result as you observed. Less code, fast to start and vastly improved error management.
- specialist 5y ago> Converting compile time errors in to runtime exceptions. Heh. Stealing this. Short, sharp, undeniable. I usually say something snarky like "Spring is an exception obfuscation framework" or "...flow of control obfuscation framework".
- geodel 5y ago> Heh. Stealing this... Yeah, please popularize it. In my case I am unable to make management see reason. If more devs become vocal about it make it a trend, it will be a good thing to happen.
- RedShift1 5y agoSame here. I've gotten rid of all that stuff, it's just layers and layers of indirection that contribute nothing. One rule that has also helped me a lot to keep my code clean and make it easier to debug is to fail as much as possible in the constructor. So when you call new MyThing(), you will either get a usable object or it'll throw an exception. Further method calls are expected to work. Of course this is not doable for everything, but it sure helps keeping the methods clean and not have them throw various exceptions.
- jicea 5y agoCould you share your Spring/Spring Boot alternatives? Are they Java based? I'm doing backend stuff with Spring Boot and I would like to test alternatives. Spring boot is not that difficult to work with, but I would like to test a "simpler" solution.
- ludovicianul 5y agoI would recommend Quakus, Microprofile, Micronaut.,
- mmcdermott 5y agoI've had similar experiences. A few years ago, I wrote a small service in plain Java, no frameworks as part of a quick change to improve performance. It worked and we all moved on. Later it was converted to Spring Boot and it slowed way down.
- xxs 5y ago> But we need netty! And then when you add thread pools, jdbc, logging, et java.util.concurrent has threadpools and pretty damn decent at that; jdbc is a part of very standard jdk, logging is part of java.util.logging. Why do you need netty (which is not a part of spring either way)? In over 23y of working with Java, I have never needed spring.
- benhoyt 5y agoWhy do "static references become a tangled mess"? In my (limited) experience with runtime DI libraries (albeit in Go) they turn clear, IDE- and debugging-friendly code where the compiler tells you at compile time if you got it wrong ... into a hard-to-debug magical soup. With static, using-the-language dependency injection, isn't the question of "how does ABC component get access to DEF?" answerable with the normal IDE/language tooling, rather than some magical library's way of doing it? You can just find the calls to a constructor and look at the arguments. My experience is based on my bad experience with runtime DI libraries, and is definitely biased against them, but I must be missing something here.
- overgard 5y agoIn my experience most DI just interferes with being able to use the IDE to track down instantiations. Ive worked on these projects that basically have these fancy runtime things to answer questions that could be answered by the IDE if it werent so obscured. I remember one project we had a fancy thing to generate a graphviz graph, and it was like neat, but we could just use find all references if we just called new. The dumb thing is most of the time only one type is ever injected. Its all hypothetical flexibility which has a cost but no benefit
- geodel 5y ago> I remember one project we had a fancy thing to generate a graphviz graph, and it was like neat, but we could just use find all references if we just called new. Ha. Calling `new` would either be an absolute enterprise Java sin or an obscure aracana. Some people are quite proud of the fact of converting compile time errors to runtime exceptions. Because you know "best practices" and all.
- kaba0 5y agoIt definitely has a benefit at scale. I’m not sure what application were you developing, but the amount of time a single instance was changed into an interface because the client wanted the n+234th little change in this special star constellation.. with DI you don’t have to write any more code, you can even use different implementations per environment (@Profile), so this is not accidental complexity in most cases. Sure, if you need a 100 lines web server that prints hello world it is an overkill, but the correct tool for the job..
- jupp0r 5y agoDependency injection does not have to be dynamic, it can totally be done at compile time. Boost DI is an example: https://boost-ext.github.io/di/ https://boost-ext.github.io/di/
- vips7L 5y agoThere’s plenty of Java frameworks that are compile time too. Quarkus, Avaje Inject, etc all do their wiring at compile time.