Yes, it is a pita, but it is a price to pay for the dependency injection, where many components, services, configs from different projects/libs have to be searched (annotations can hide everywhere), started and then wired together in the order they define 'globally'. And once you change a config property, that tree can change as well.
I hope some work will be done there. One could scan the libs in parallel, caching results, building/shipping a search tree on packaging time and so on.
In pure servlet times you could directly define your starting points, define, which libs to exclude or include for the search and so on.
At least no one has to edit xml files anymore to wire components and impls together.
This statement doesn't necessarily generalize, but I can't say I'm a huge fan of what the Spring-flavoured Dependency Injection ended up looking like around here either. It's like... we've taken on ridiculously long startup times, to turn what would be compile-time errors into run-time errors. Seems like a double-whammy of bad.
Maybe I'm a little overly jaded, but the Java apps I've worked on (which is admittedly only a handful) have all had these giant sprawling messes of dependencies; it feels like there's a lot of code to accomplish very little. The Golang-based services I've worked on feel like the opposite; very little code to accomplish a lot of things, without much ceremony.
Edit: And that's not to say that I'm opposed to dependency injection; rather, I'm quite happy to do constructor-based dependency injection by hand. When that starts to feel painful, I look at the system I'm working on and wonder if it's getting too complicated/has too much coupling/etc.
I do not know golang-services. But in the end, somewhere is the code written and it must be shipped, started, maintained and so on. Someone must also write the drivers for used technologies and must bring them into the golang world.
For us as a little company without access to many developers with affordable pay expectations, it is a big relieve, that a lot of specialist knowledge is bundled together in spring. Such as how to do central configuration, logging, monitoring, failover, loadbalancing, streaming, backpressure support, db connection pooling, message queuing, and so on. And you need special knowledge only when something fails. And when it fails, you can assume, its done the same on each service. It helps a lot. You have then a wider pool of people you can ask to help you to do the actual business coding work.
It reminds me a little on how maven defaults said: code belongs into src/main/java and test below src/test/java and then have a little pom.xml,that describes your project. It has brought sooo much relieve to get rid of so many flavors, how people have structured the code. Not to forget the style of make scripts. You can now open many projects in any IDE without any hassle, you do not have to search forever, where the starting point is and so on. I always forget that. Less work for my little brain, when navigating between projects.
So, even with the dependency hell (i totally agree), i am ok with it, as i seem to forget, what i dont have to do on each individual service anymods. And i have access to a rich ecosystem, that is maintained and supported and people react on issues.
I generally agree! The unfortunate thing for me is that when that stuff breaks in some obscure way, I end up being the one to debug it. Magically having private fields populated during application launch is great, until the junior guys can't figure out why one of them is null sometimes.
Yes i share the pain with you. When it does not work, you still must have a senior or a junior willing to dig into it and become senior after some time as well. Pushing the responsibility away to magic sauce is good and bad. Yup.
Take a look at dagger2. It does compile-time dependency injection through generated .java files, so it wastes no time scanning classes at runtime, and you can look at the quite readable generated source code to see exactly what it's doing.
Well, I figure if that was ported to C it still would take a while to start. I don't think it necessarily demonstrates that the JVM is too slow for command line apps. Just more that Spring takes a while to startup.
That's the thing... I've been porting some of the functionality to Golang, and slicing out many layers of abstraction and baggage at the same time. There's some tradeoffs; e.g. I'm actually writing some SQL queries instead of just declaring interfaces that JPA auto-populates with methods, but overall it just feels like a way lighter and less magical codebase.
I see, how you are writing your go code sounds similar to how we wrote our code on the JVM. e.g. We didn't use Spring or other enterprise frameworks like that and would write pretty much direct SQL with jdbc (after several misadventures in various Scala db-wrappers de-jour).