Внедрение статического EJB, вздор?

Я хочу написать этот фрагмент кода:

@Stateless
public class MyEjb
{
    @EJB
    private static MyOtherEjbWhichIWantStatic myOtherEjb;
}

Мне кажется, что я хочу ввести EJB в свой класс, как статический элемент, по разным причинам.

Java не очень доволен тем, что, к сожалению,

com.sun.enterprise.container.common.spi.util.InjectionException: Illegal use of static field private static MyOtherEjbWhichIWantStatic myOtherEjb on class that only supports instance-based injection

Я не понимаю, почему я не могу вставить статический EJB в другой EJB?

Ответ 1

Как указывали другие, это не допускается спецификацией, а короткая версия заключается в том, что аннотация @EJB поддерживается только для статических членов в классах с функцией main() (см. спецификацию EJB 3.0 и приложение клиентский контейнер).

Почему так? Во-первых, чтение/запись статических полей полностью запрещено в EJB (это часть ограничения EJB). Из Почему я не могу использовать нефинальные статические поля в моем предприятии bean?

Нефинальные поля статического класса запрещены в EJB, потому что такие поля делают предприятие bean трудным или невозможным для распространения. Поля статических классов распределяются между всеми экземплярами определенного класса, но только внутри одной виртуальной машины Java (JVM). Обновление поля статического класса подразумевает намерение использовать значение поля для всех экземпляров класса. Но если класс работает в нескольких JVM одновременно, только те экземпляры, которые работают в одной JVM как экземпляр обновления, будут иметь доступ к новому значению. Другими словами, нефинальное статическое поле класса будет вести себя по-разному, если работает в одном JVM, чем в нескольких JVM. Контейнер EJB резервирует возможность распределения предприятия beans на нескольких JVM (работающих на одном сервере или на любом кластере серверов). Нефинальные поля статического класса запрещены, поскольку экземпляры предприятия bean будут вести себя по-разному в зависимости от того, распространяются они или нет.

Допустимо использовать поля статического класса, если эти поля отмечены как final. Поскольку окончательные поля не могут быть обновлены, экземпляры предприятия bean могут быть распределены контейнером без учета того, что значения этих полей становятся несинхронизированными.

Но при использовании разрешенных статических полей только для чтения это не подходит для EJB. Безъядерные EJB могут быть объединены, контейнер может принять решение об их уничтожении (это конкретная реализация), и вы хотите разрешить контейнеру выбирать, какой экземпляр вы собираетесь использовать, особенно в распределенных средах. Другими словами, никогда не предполагайте, что вы привязаны к определенному экземпляру.

Итак, в конце, да, это вздор.

Ответ 2

Я не понимаю, почему я не могу статический EJB в другой EJB?

Потому что спецификация не позволяет:

5.2.3. Обозначения и инъекции

Как описано ниже разделы, поле или метод определенных классы компонентов, управляемых контейнерами могут быть аннотированы, чтобы потребовать, чтобы запись из компонентов приложения окружающей среды класс. [...] Для всех классов, кроме основных классов клиента приложения, полей или методов не должно быть статичным.

Обратите внимание, что исключение (основные классы клиента приложения) существует только потому, что эти классы никогда не создаются. В принципе, статические поля обычно проблематичны и вдвойне на сервере приложений, поскольку они могут обойти разделение потоков обработки запросов и транзакций, которые в первую очередь используют сервер приложений.

Ответ 3

Из спецификации Java EE 5 вставка статических EJB разрешена только в основных классах клиента приложения.

Для всех классов, кроме основных классов клиента приложения, поля или методы не должны быть статическими. Поскольку клиенты приложений используют тот же жизненный цикл, что и приложения J2SE, экземпляр основного класса клиента приложения не создается контейнером клиента приложения. Вместо этого вызывается статический основной метод. Чтобы поддерживать инъекцию для основного класса клиента приложения, поля или методы, аннотированные для инъекций, должны быть статическими.