2. It is derived from the desire to create not applications, but application frameworks that can handle any conceivable change request that the PO might come with. This is architecture astronaut territory. It's frustrating to work with. It's hateful to debug.
2) the ThreeProvider example is contrived indeed. In real projects this is used to provide different implementations for loggers, or sms gateways or other things that can differ between environments (prod, dev, test)
And to decouple the construction of objects from their usage. For example a rest api controller should not care how to instantiate a database connection and associated code, it should just require an implementation of a Repository interface for the model it uses.
The principle of dependency injection is a good one, but dependency injection frameworks are an unnecessary and overcomplicated way of achieving it. XML-based DI frameworks at least had a rationale - the idea was to externalise configuration, so you could change the dependencies without changing the code. It turns out this kind of externalisation isn't actually valuable in most cases (changing the dependencies is just as complicated and risky as changing code, and often needs to be coordinated with more substantive code changes, so the separation is artificial).
Once you determine that you should wire up your dependencies in code, though, there's no need for dependency injection frameworks - you can just directly write the code that wires up the dependencies.
> dependency injection frameworks are an unnecessary and overcomplicated way of achieving it.
But why? I don't want to write my own DI framework for each new project.
I'd better add one dependency, put some @Autowired (and other well-documented) annotations and continue writing business logic.
Aforementioned 'magic' is basically creating a context, scanning all annotations, registering beans, instantiating them (calling constructors), then injecting them.
1. I launch the app
2. Spring does a bunch of stuff I only vaguely understand and can't understand from looking at the code
3. My actual code starts running
On top of that, all the spring stuff makes the memory footprint and startup time awful.
Ideally, making something automated should not make it harder to do the same thing manually.