Ein sehr wichtiger Bestandteil von Spring ist die Verwaltung von Beans und die damit verbundene Dependency Injection.
Du kannst also Beans definieren - sowohl über Annotations als auch über entsprechende Config-Files und diese dann jederzeit laden.
Das ist ein Vorteil in meinen Augen: Du musst Dir nichts merken, keine Singleton schreiben und so ...
Du definierst das als Bean. Also z.B. mit der @Component (org.springframework.stereotype.Component) Annotation.
Und wenn Du dann in einem anderen Bean diese Komponente benötigst, dann kannst Du da einfach mittels @Inject sagen, dass Du den Bean brauchst:
@Inject private SomeCoolBean coolBean;
Wenn Du nun auf Grund einer Konfigurationsdatei unterschiedliche Implementationen haben willst, dann kannst Du das auf diverse Wege implementieren:
a) Du kannst für diesen SomeCoolBean mehrere Implementationen haben und Du gibst dann in einer Spring Config Datei an, welche Klasse da verwendet werden soll. In dem Zusammenhang kannst Du dann auch Werte für Konstruktoren oder Setter angeben.
b) Wenn Du eigene Config-Dateien haben willst, dann könntest Du in dem Bean natürlich diese beliebige Datei laden und dann basierend auf dem, was Du da geladen hast, irgendwas im Bean erstellen.
Mir gefällt a) sehr gut, da es problemlos erweiterbar ist. Wenn jemand da eine eigene Version von SomeCoolBean schreiben sollte, dann kann er dies problemlos einbinden. Er muss halt nur Dein Interface implementieren und dann sein jar mit hinzufügen.
Wie so Beans in einem XML File beschrieben werden können, findest Du z.B. hier:
https://www.tutorialspoint.com/spring/spring_bean_definition.htm
Aber zu spring gibt es insgesamt sehr viel wie Du bestimmt schon gesehen hast.