Ответ 1
Хорошее объяснение концепций, лежащих в основе, приведено в этом Article Адамом Биеном.
im немного путают. Какая разница между javax.inject.Singleton
и javax.ejb.Singleton
?
Хорошее объяснение концепций, лежащих в основе, приведено в этом Article Адамом Биеном.
Я нашел правдоподобное объяснение здесь:
По умолчанию
javax.ejb.Singleton
session beans являются транзакционными (раздел 13.3.7 спецификации EJB 3.1) и требуют приобретения исключительной блокировки для каждого вызова бизнес-метода (разделы 4.8.5.4 и 4.8.5.5).Напротив,
javax.inject.Singleton
не является транзакционным и не поддерживает управляемый контейнером concurrency (главным следствием является то, что контейнер не реализует схему блокировки). [...]Если вам не нужны функции EJB, придерживайтесь
@ApplicationScoped
(javax.inject.Singleton
не определяется CDI, поэтому его семантика не регулируется этой спецификацией).
Так как принятый ответ не решил мою проблему, я отправляю свой собственный ответ. Это будет не так хорошо, как статья Адама Биена, но определенно будет более практичным:
Рассмотрим следующий код:
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.
Однако при замене ejb
при импорте inject
вы получили бы NPE в классе ChampionsAPI при доступе к полю db - это потому, что ваш Singleton не был создан (по какой-то причине, возможно, потому, что нужно использовать интерфейсы при использовании javax.inject.Singleton
?).