The solution hides the problem. I enjoyed reading about the details of the insides of Spring, but the solution was too complicated for the problem. A real value of Spring is that generally it does not get in the way of straightforward solutions. The problem here, picking a datasource based on key could have been handled with a simple DataSource delegate that can pick the actual datasource from an injected mapping of key to datasource. The management of the mapping would be done elsewhere -- JMX, webapp, etc.
For me, the red flag would have been when I thought the solution required a weekend of prototyping to understand the internals of Spring.
This is off topic, but related to picking solutions. You also need to think about the person maintaining your solution. A complex solution will require that the maintainer be at least as talented as you and that can be an unnecessary burden on the organization.
Is a whole book needed to tell you to solve problems by enumerating the subproblems, stop enumerating when you find one with few dependencies, visualize the dependencies, fix the subproblem, revert the fix when necessary, rinse and repeat. Oh, and give the method a catchy name like The Mikado Method. I don't think so.
Update: This comment was a bit too snarky. I sometimes forget that junior developers do need to be reminded of the basics. And being able to name this is important as the Gang of Four confirmed for us with Design Patterns: Elements of Reusable Object-Oriented Software.
"I no longer have patience for certain things, not because I've become arrogant, but simply because I reached a point in my life where I do not want to waste more time with what displeases me or hurts me. I have no patience for cynicism, excessive criticism and demands of any nature. I lost the will to please those who do not like me, to love those who do not love me and to smile at those who do not want to smile at me. I no longer spend a single minute on those who lie or want to manipulate. I decided not to coexist anymore with pretense, hypocrisy, dishonesty and cheap praise. I do not tolerate selective erudition nor academic arrogance. I do not adjust either to popular gossiping. I hate conflict and comparisons. I believe in a world of opposites and that's why I avoid people with rigid and inflexible personalities. In friendship I dislike the lack of loyalty and betrayal. I do not get along with those who do not know how to give a compliment or a word of encouragement. Exaggerations bore me and I have difficulty accepting those who do not like animals. And on top of everything I have no patience for anyone who does not deserve my patience." -- Meryl Streep
When designing an API I use the "get vs find rule." The API's user needs to know how to handle the absence of a result. A get is expected to always return a result while a find is not. And so when coding "getX()" it returns the result or throws an exception -- such as IllegalStateException -- if there is not one. Where as, when coding "findX()" it returns a result if available or a null, or an empty collection, if there not one.