"If it ever came time to switch payment gateway backends, in a Java application using DI you would just need to switch which implementation of your interface that the rest of your code is wired up with (either in XML, or if you are wiring up collaborators explicitly in your code, etc)."
You simply pass in the desired payment processor as a parameter. End of story.
This is part of the reason Java is such a terrible language for actually learning about programming. "Using Dependency Injection" is an absurd way of phrasing "pass in varying parameters as parameters to your function instead of using global variables". What should be the normal way of doing business has instead been elevated to Something Special (that Lesser Languages Can't Do because they don't call it Dependency Injection because they would never think of giving Passing Parameters to Functions a special name!) because Java makes something as easy as breathing and in some cases hard to avoid (try programming Haskell or Erlang with too many global variables) a production.
In Java, you use absurd and unnecessary machinery. In every other language, you just do it. It's hard to even explain how you do it because there's hardly any doing in the it. It's a parameter passed in. It hardly seems worth discussion.
For the sake of this example, let's say that the different gateways have vastly different APIs, messaging mechanisms, etc.
So in the code that you are passing a parameter to, you'd have to have some sort of branch based on the parameter value to choose to call Gateway A versus Gateway B - correct?
Which requires you, when switching gateways, to change the value of the parameter passed along with possibly updating the branch to be aware of what the different Gateway modules you might call would be - correct?
This is basic object orientation: You pass in an object that corresponds to the desired interface. "Facade pattern" if you need something to Google, but this is really basic language-agnostic OO stuff.
Another reason to dislike the Java cruft; it successfully hides the simple things going on behind immense machinery and complicated terminology.
You simply pass in the desired payment processor as a parameter. End of story.
This is part of the reason Java is such a terrible language for actually learning about programming. "Using Dependency Injection" is an absurd way of phrasing "pass in varying parameters as parameters to your function instead of using global variables". What should be the normal way of doing business has instead been elevated to Something Special (that Lesser Languages Can't Do because they don't call it Dependency Injection because they would never think of giving Passing Parameters to Functions a special name!) because Java makes something as easy as breathing and in some cases hard to avoid (try programming Haskell or Erlang with too many global variables) a production.
In Java, you use absurd and unnecessary machinery. In every other language, you just do it. It's hard to even explain how you do it because there's hardly any doing in the it. It's a parameter passed in. It hardly seems worth discussion.