[英]Difference between javax.inject.Singleton and javax.ejb.Singleton
我有點困惑。 javax.inject.Singleton
和javax.ejb.Singleton
之間的確切區別是什么?
我在這里找到了一個合理的解釋:
默認情況下,
javax.ejb.Singleton
會話 bean 是事務性的(EJB 3.1 規范的第 13.3.7 節)並且需要為每個業務方法調用獲取排他鎖(第 4.8.5.4 和 4.8.5.5 節)。相比之下,
javax.inject.Singleton
不是事務性的,不支持容器管理的並發(主要結果是容器沒有實現鎖定方案)。 [...]如果您不需要 EJB 功能,請堅持使用
@ApplicationScoped
(javax.inject.Singleton
不是由 CDI 定義的,因此它的語義不受該規范的約束)。
為了減少以后的混淆,我使用了這個小單元測試(第一級包名需要替換):
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import org.junit.Test;
public class SingletonTest {
/** requires com.tngtech.archunit:archunit-junit:0.4.0 */
@Test
public void detectWrongSingletonAnnotation() {
final ClassFileImporter importer = new ClassFileImporter();
final JavaClasses classes = importer.importPackages("first_level_package");
noClasses().should().beAnnotatedWith("javax.inject.Singleton")
.as("Please use javax.ejb.Singleton instead of javax.inject.Singleton.")
.check(classes);
}
}
由於接受的答案沒有解決我的問題,我發布了我自己的答案。 它不會像 Adam Bien 的文章那么好,但肯定會更實用:
考慮以下代碼:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
@Singleton
public class DatabaseConnection {
@PostConstruct
public void init() {
System.out.println("init");
}
public ChampionComp getFirstRecord() {
return new ChampionComp("Ashe", "Teemo", "Warwick",
"Blitzcrank", "Syndra", "Anivia", "Brand", "Rammus", "Xin Zhao", "Irelia");
}
}
這個 REST 服務:
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
@Path("/champions")
public class ChampionsAPI {
@Inject
private DatabaseConnection db;
@GET
@Produces("text/plain")
public String getClichedMessage() {
ChampionComp comp = db.getFirstRecord();
return comp.toString();
}
}
使用javax.ejb.Singleton
這段代碼工作得很好。 DatabaseConnection
實例創建一次並注入到 REST 服務。 但是,當使用inject
替換導入中的ejb
,您會在訪問 db 字段時在 ChampionsAPI 類中收到 NPE - 那是因為您的 Singleton 未創建(出於某種原因,可能是因為在使用javax.inject.Singleton
需要使用接口?) .
簡單明了:
javax.ejb.Singleton 是用於創建@Singleton EJB(與@Sateless EJB 或@Stateful EJB 相對)的注解
另一方面,javax.inject.Singleton 是一個注解,用於創建具有單例范圍的 CDI
所以基本上,一個創建一個單例 EJB 而另一個創建一個具有單例范圍的 CDI
的概念很好地解釋背后在此給出的文章被亞當邊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.