在CDI中有@ApplicationScoped
和(javax.inject
)@Singleton
伪作用域。它们之间有什么区别?除了@ApplicationScoped
被代理和@Singleton
不被代理的事实。
我可以把@Singleton
豆换成@ApplicationScoped
吗?@ApplicationScoped
bean 可以有两个(或更多)实例吗?
在CDI中有@ApplicationScoped
和(javax.inject
)@Singleton
伪作用域。它们之间有什么区别?除了@ApplicationScoped
被代理和@Singleton
不被代理的事实。
我可以把@Singleton
豆换成@ApplicationScoped
吗?@ApplicationScoped
bean 可以有两个(或更多)实例吗?
Answers:
@Singleton
不是CDI规范的一部分。它是EJB和javax.inject
(JSR-330)的一部分。规范中没有提到它的行为,因此您只能依靠Weld文档中的内容。
@Singleton
。仅在一个示例中显示,没有任何说明。CDI确实依赖于javax.inject
,但严格来说,它不是CDI规范的一部分。就是说,我稍微纠正了我的答案。
简而言之:您甚至可以将其(@Singleton
和@ApplicationScoped
)混合使用,并且在某些情况下很有意义。
(并且按我的预期工作!)
除了到目前为止的其他答案外,我想补充一些要点,以便在现实世界中进行说明。
对我来说,这个问题源于我如何强制应用程序范围的bean在应用程序启动时实例化? 在一些讨论中,我说了这一点,到目前为止,找不到针对它的有效论点:
在很多实际场景/设置中,从抽象/建模的角度来看,我很难说肯定是-某事物是(或将被视为)EJB或应用程序范围内的受管bean。
到目前为止(从我的角度来看)的争论(有争议但不是决定性的):(@ BalusC和所有其他人:我希望看到他们具有决定性,但如果不是,则以上说法可能成立,尽管如此,论点仍可能成立仍然可以帮助读者了解差异/优势/劣势/不良/良好做法)
BalusC:这是EJB而不是托管bean,这是完全不同的。EJB在后端运行,在托管Bean在前端运行。EJB也运行在事务上下文中。[...]您只是将企业bean与托管bean混淆了,我只是指出了这一点。
但:
我:我认为您不太正确并且夸大了其含义/用法,这对我来说值得商bat。http://en.wikipedia.org/wiki/Enterprise_JavaBeans
Enterprise JavaBeans(EJB)是用于模块化构建企业软件的托管服务器软件,并且是几种Java API之一。EJB是一个服务器端软件组件,封装了应用程序的业务逻辑。
企业Bean的类型
可以为“有状态”,“无状态”或“单人”的会话Bean [3] [...]
消息驱动的豆[...]
...在我看来仍然如此。
BalusC:单例EJB与应用程序范围的bean不同。单例EJB被读/写锁定,因此对于您所考虑的任务可能效率低下/卷积过多。长话短说:拿一本好的Java EE书,学习使用正确的工具来完成这项工作。一种方法肯定不是另一种方法。它起作用并不意味着它是正确的工具。大锤可以固定螺丝,但不一定是正确的工具:)
但:
(我在这里看不到大锤,对不起...)很高兴知道锁定默认值(我没有意识到),但这似乎又是不正确的:Oracle Java EE 6教程中的 “ 管理并发访问”。单例会话Bean
创建单例会话bean时,可以通过两种方式控制对单例业务方法的并发访问:容器管理的并发和bean管理的并发。[...]
尽管默认情况下,单例使用容器管理的并发,但可以在单例的类级别添加@ConcurrencyManagement(CONTAINER)批注以显式设置并发管理类型
通常,当您只希望某个对象的一个实例时,您可能应该使用@ApplicationScoped
批注-该对象被代理,因此甚至可以即开即用地正确序列化。
另一方面,在很多情况下,您只需要该类的一个实例,但是无法代理该类(例如,因为是最终的),这@Singleton
是一种拯救。因为Singleton
是伪作用域,并且不像任何“正常”范围那样被代理。
@ApplicationScoped
和之间的实际差异的一些解释@Singleton
。