At first I recommend reading this question (well, its answer): What are drawbacks or disadvantages of singleton pattern? and this: What is dependency injection?
Singleton pattern is about object existing in a single instance, so that it can be used in multiple places. Problem is not with the concept of a singleton, but how it is frequently implemented (through some statically accessed field/method).
So, what you need is a singleton object, but without all the problems mentioned above.
Therefore in the class (which you want to be a singleton), just define all those maps as normal fields, add all the methods you need as well as its dependencies (that should be injected through constructor).
Once that class is defined, you just need to:
- create single object of it
- provide it to other objects (that needs access to it) when creating them (ideally through their constructor, or a setter method).
How to implement above two points depends on your application. You basically need a dependency injection system.
- You can manually implement it, which basically means having a factory method that creates all singleton objects and wires them together).
- If you use spring, then you can rely on its dependency injection capabilities (In this case you just annotate your singleton with
@Component
and inject to other components with @Autowired
).
- You can even setup dependency injection yourself using for instance https://github.com/google/guice
However, if it's your first contact with the concept of dependency injection. I recommend implementing it manually, this way you'll understand better how above mentioned dependency injection frameworks work.