Внедрить статический EJB, чепуха? - PullRequest
11 голосов
/ 07 июля 2010

Я хочу написать этот кусок кода:

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

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

К сожалению, я не очень доволен этим

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?

Ответы [ 3 ]

26 голосов
/ 07 июля 2010

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

Почему это так? Прежде всего, статические поля чтения / записи полностью запрещены в EJB (это является частью ограничения EJB). С Почему я не могу использовать незавершенные статические поля в своем корпоративном бине?

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

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

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

Так что, в конце концов, это чепуха.

1 голос
/ 07 июля 2010

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

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

5.2.3 Аннотации и инъекции

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

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

0 голосов
/ 07 июля 2010

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

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

...