Hilt中Dao对象是否需添加@Singleton注解的疑问
核心结论
当你通过Hilt将Room Database标记为@Singleton后,从该Database获取的Dao实例实际运行时会自动成为单例,但从Hilt的注解规范和代码可读性角度,建议为Dao的provide方法也添加@Singleton注解。
详细解释
Room本身的机制决定Dao的单例性
Room的Database类内部会为每个Dao维护一个唯一实例——也就是说,只要是同一个Database对象,无论你调用多少次getPlantDao()或getGardenPlantingDao(),返回的都是同一个Dao实例。既然你的Database是Hilt提供的单例,那么从它拿到的Dao自然也会是单例,哪怕Dao的provide方法没有加@Singleton。Hilt的注解语义与实际行为的差异
Hilt默认会根据provide方法的作用域注解来管理实例:如果没有标注@Singleton,Hilt的默认策略是每次注入都执行一次provide方法。但因为你每次都是从同一个单例Database中获取Dao,所以最终返回的还是同一个对象。不过这里存在语义不明确的问题:没有@Singleton注解的话,Hilt的元数据里不会标记这个依赖是单例,其他开发者可能会误以为Dao是多例,后续如果修改Database的作用域,Dao的实例行为也会跟着改变。Google Sunflower写法的合理性与最佳实践
Sunflower示例中不为Dao的provide方法加@Singleton,是因为从实际运行效果来说完全没问题,但这更偏向于“极简写法”。而大部分教程要求加@Singleton,是遵循Hilt的作用域规范——让依赖的作用域明确可见,避免潜在的误解和后续维护问题。
最终建议
- 如果追求极简,且确定Database的单例作用域不会改变,不加
@Singleton也能正常运行; - 从代码可读性、维护性和Hilt规范出发,强烈建议为Dao的provide方法添加
@Singleton注解,让依赖的生命周期和作用域一目了然。
内容的提问来源于stack exchange,提问作者WHOATEMYNOODLES

