Разница между javax.inject.Singleton и javax.ejb.Singleton

im немного путают. Какая разница между javax.inject.Singleton и javax.ejb.Singleton?

Ответы

Ответ 1

Хорошее объяснение концепций, лежащих в основе, приведено в этом Article Адамом Биеном.

Ответ 2

Я нашел правдоподобное объяснение здесь:

По умолчанию 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, поэтому его семантика не регулируется этой спецификацией).

Ответ 3

Так как принятый ответ не решил мою проблему, я отправляю свой собственный ответ. Это будет не так хорошо, как статья Адама Биена, но определенно будет более практичным:

Рассмотрим следующий код:

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?).