使用CDI对性能的影响

Tro*_*oup 9 java cdi java-ee-6 jboss-weld jboss7.x

我正在编写一个Java EE 6 Web应用程序,我注意到在使用注入对象与直接创建和使用对象时会对性能产生重大影响.每个方法调用的开销似乎是50-60ms.

例如,使用非注入150方法调用大约需要500毫秒,而使用注入对象150方法调用需要12,000 - 13,000毫秒.一个数量级的差异然后一些.

这通常吗?

我在JBoss AS 7.1.1 final上运行,它使用Weld来处理CDI.

注入的对象被定义为单例bean(通过javax.ejb.Singleton注释).这会导致部分问题吗?或者只是Weld代理导致减速?

Tro*_*oup 10

在优秀的Weld论坛的帮助下,我发现:

默认情况下,单例会话bean是事务性的(EJB 3.1规范的第13.3.7节),并且需要为每个业务方法调用获取独占锁(第4.8.5.4节和第4.8.5.5节).相反,javax.inject.Singleton不是事务性的,并且不支持容器管理的并发(主要结果是容器没有实现锁定方案).

如果使用@TransactionAttribute(NOT_SUPPORTED)和@Lock(READ)注释单个会话bean,您应该会看到明显更好的性能,尽管可能仍有一些开销.如果您不需要EJB功能,请坚持使用@ApplicationScoped(javax.inject.Singleton不是由CDI定义的,因此其语义不受该规范的约束).

https://community.jboss.org/thread/213684?tstart=0

遗憾的是,即使用@TransactionAttribute(NOT_SUPPORTED)和@Lock(READ)注释我的EJB单例之后,性能仍然非常差(参见原帖的时间).

所以带回家的消息是不要注入EJB Singleton会话bean,除非你绝对必须,甚至那时要注意可能产生的性能开销.对于很少被调用的方法,它可以忽略不计,但在我们的情况下,如果它是一种使用频繁的方法,则小的开销会迅速累积.

我们不需要EJB功能,并且在切换到ApplicationScoped时,看到了调用注入bean的特定方法的性能的数量级改进.