← Back to context

Comment by __float

3 days ago

As someone who has used Java pretty extensively for a few years (but in an environment where Spring was forbidden), why is that?

You’ll find differing opinions.

As someone who has worked on code bases that did not have spring that really should have and had to do everything manually: when used well it’s fantastic.

Now people can certainly go majorly overboard and do the super enterprise-y AbstractBoxedSomethingFactoryFacadeManagerImpl junk. And that is horrible.

But simple dependency injection is a godsend. Ease of coding my just adding an annotation to get a new component you can reference anywhere easily is great. Spring for controllers when making HHTP endpoints? And validation of the data? Love it!

Some of the other modules like Spring Security can be extremely confusing. You can use the Aspect Oriented Programming to go overboard and make it nearly impossible to figure out what the hell is happening in the program.

Spring is huge, and it gets criticized for tons of the more esoteric or poorly designed things it has. But the more basic stuff that you’re likely to get 90+ percent of the value out of really makes things a lot better. The relatively common stuff that you’ll see in any Spring Boot tutorial these days.

  • Actually I really dont like DI and its a core of my dislike. I can easily create objects directly and pass in dependencies, its a lot easier to debug and see what is going on as opposed to Spring magic.

    • Passing a couple objects seems easy. But I’ve seen where it leads in a large program.

      Passing things down layer after layer gets old. High level stuff takes tons of parameters due to all the layers below.

      You end up with God objects that mostly just contain every other object someone might want to reference.

      And you know what? That object starts to feel like a great place to put state. Cause it’s already being passed everywhere.

      So instead of using Spring to get a ThingService to work with your Thing at the spot you need it, suddenly all the code has access to all the stuff and states. And like the temptation of The One Ring programmers use it.

      Now you have a spaghetti rats nest. Where is the code that deals with the state for a Gloop? It’s now everywhere. Intertwined with the code for a Thing. And a Zoob. It doesn’t need to be. But it is.

      It becomes almost impossible to unit test things. Because everything can do/see everything. Untangling and extracting or replacing any part of the whole is a Herculean job.

      You don’t need Spring for something tiny. And maybe it’s possible to go without dependency injection in a large app and keep things manageable and easy to understand.

      In my career I’ve mostly seen the mess. I’ve helped try to untangle it by slowly introducing Spring.

      I’d rather have it, with its organization and standard patterns, than the Wild West of whatever any programmer or junior decided to do over the last 15 years and how that has evolved. In a complex application with lots of programmers coming and going I find it a net benefit.

    • > Actually I really dont like DI and its a core of my dislike. I can easily create objects directly and pass in dependencies...

      So you DO like DI, you just do it explicitly. Which is fine.

    • I mean if you just follow the common usage patterns of Spring Boot, it is not really magic - just stick to the core annotations and not more. It does require one to have basic familiarity with Spring Boot but I don't think that is an unreasonable ask. And like many things, people can go totally overboard and make it an impenetrable mess but I think that is on the programmer, not the framework.

The beautiful and essential technique of DI (dependency inversion) got namesquatted hard by DI (dependency injection).

Before, you used to write "loosely coupled" software by decoupling your business logic from your IO to keep it testable. You could take virtually anything worth testing, 'new' it in a unit test, and bob's your uncle.

Now you write "loosely coupled" software by keeping the coupling between components, but also couple them to a bunch of Spring dependencies too (check your imports!). Now you can't instantiate anything without Spring.