@Singleton和@ApplicationScoped都是应用范围的bean,主要区别在于:
@Singleton:
- bean的实例在第一次注入时创建,之后始终使用同一个实例。
- 可以直接访问bean的字段,因为始终是同一个实例。
- 不支持mock,因为没有代理可以拦截方法调用。
- 略微更高的性能,因为没有代理的开销。
@ApplicationScoped:
- bean的实例在第一次方法调用时创建,注入点注入的是一个代理。
- 不能直接访问bean的字段,需要通过方法调用,因为注入的是一个代理。
- 支持mock,可以使用Mockito或Quarkus Mock来mock @ApplicationScoped bean。
- 可以在运行时重新创建实例,注入点无需变化,因为注入的一直是代理。
所以,总体来说:
如果需要直接访问bean的状态,选择@Singleton。
如果需要mock或在运行时重新创建实例,选择@ApplicationScoped。
除非有明显的性能要求,否则推荐默认使用@ApplicationScoped,因为它更灵活和易测试。只有当直接访问bean状态或有较高的性能要求时,才使用@Singleton。
两者的其他方面,如作用域、代理、延迟初始化等行为都是相同的。所以除上述区别外,在大多数情况下可以互换使用。