Search code examples
kotlindesign-patternssingletonmicronaut

When is it appropriate to use @Singleton and @Prototype in Micronauts?


I read so many bad things about singleton pattern (What is so bad about singletons?), however, @Singleton is used everywhere in this Micronaut doc to illustrate inversion of control https://docs.micronaut.io/1.3.0.M2/guide/index.html#ioc

When is it appropriate to use @Singleton? For example, if I have a UserInfoService that has getUserInfo, createUserInfo, updateUserInfo method, is it a good idea to use @Singleton?

Another separate question is when do I use @Prototype, because if I don't use any annotation for a function/class, isn't it by default a prototype (as in I initiate a new instance of it in another class/function)?


Solution

  • When is it appropriate to use @Singleton? For example, if I have a UserInfoService that has getUserInfo, createUserInfo, updateUserInfo method, is it a good idea to use @Singleton?

    UserInfoService should almost certainly be a stateless singleton.

    Another separate question is when do I use @Prototype, because if I don't use any annotation for a function/class, isn't it by default a prototype (as in I initiate a new instance of it in another class/function)?

    If you initiate a new instance, then the annotation doesn't matter. The annotation only affects instances that the Micronaut container creates for you. For @Singleton the container creates a single instance and injects the same instance at all injection points that require it. For @Prototype the container creates a new instance for each injection point.

    All of this is about application design more than it is about Micronaut. Micronaut provides a simple mechanism for you to declaratively express (by way of @Singleton or @Prototype) whether or not you want the same instance to be shared or not but the issue is really about application design. In general you should prefer stateless singletons. If for some reason you have a bean that must be stateful and you have good reasons to not want to share instances from different contexts, then @Prototype might be appropriate.

    I hope that helps.