Прежде всего позвольте мне сделать некоторые пояснения:
Определение управляемого компонента : обычно управляемый компонент - это объект, жизненный цикл которого (создание, разрушение и т. Д.) Управляется контейнером.
В Java ee у нас есть много контейнеров, которые управляют жизненным циклом своих объектов, таких как контейнер JSF, контейнер EJB, контейнер CDI, контейнер сервлетов и т. Д.
Все эти контейнеры работают независимо, они загружаются при инициализации сервера приложений и сканируют классы всех артефактов, включая файлы jar, ejb-jar, war и ear, во время развертывания, а также собирают и хранят некоторые метаданные о них, а затем, когда вам нужен объект класса во время выполнения они предоставят вам экземпляры этих классов и после завершения работы уничтожат их.
Итак, мы можем сказать, что у нас есть:
- Управляемые компоненты JSF
- Управляемые компоненты CDI
- EJB-управляемые компоненты
- И даже сервлеты являются управляемыми компонентами, поскольку они создаются и уничтожаются контейнером, который является контейнером сервлета.
Поэтому, когда вы видите слово Managed Bean, вы должны спросить о контексте или его типе (JSF, CDI, EJB и т. Д.)
Тогда вы можете спросить, почему у нас много таких контейнеров: AFAIK, ребята из Java EE хотели иметь структуру внедрения зависимостей, но они не могли собрать все требования в одной спецификации, потому что они не могли предсказать будущие требования, и они сделали EJB 1.0, а затем 2.0, а затем 3.0 и теперь 3.1, но целью EJB было лишь выполнение некоторых требований (транзакция, модель распределенных компонентов и т. Д.).
В то же время (параллельно) они поняли, что им тоже нужна поддержка JSF, затем они сделали управляемые bean-компоненты JSF и еще один контейнер для JSF-компонентов, и они посчитали его зрелым контейнером DI, но все же это не был законченный и зрелый контейнер.
После этого Гэвин Кинг и еще несколько хороших парней;) сделали CDI, который является наиболее зрелым контейнером DI, который я когда-либо видел. CDI (вдохновленный Seam2, Guice и Spring) был создан, чтобы заполнить пробел между JSF и EJB и множеством других полезных вещей, таких как внедрение pojo, методы производителя, перехватчики, декораторы, интеграционный SPI, очень гибкий и т. Д., И он даже может делать то, что делают управляемые компоненты EJB и JSF, тогда у нас может быть только один зрелый и мощный контейнер DI. Но по какой-то обратной совместимости и по политическим причинам ребята из Java EE хотят сохранить их !!!
Здесь вы можете найти разницу и варианты использования для каждого из этих типов:
Управляемые компоненты JSF, компоненты CDI и EJB
Первоначально JSF был разработан с собственным управляемым bean-компонентом и механизмом внедрения зависимостей, который был расширен в JSF 2.0 для включения bean-компонентов на основе аннотаций. Когда CDI был выпущен вместе с Java EE 6, он считался фреймворком управляемых компонентов для этой платформы и, конечно же, EJB устарели, поскольку существовали уже более десяти лет.
Проблема, конечно, заключается в том, чтобы знать, какой из них использовать и когда их использовать.
Начнем с простейших JSF Managed beans.
Управляемые компоненты JSF
Короче говоря, не используйте их, если вы разрабатываете для Java EE 6 и используете CDI. Они предоставляют простой механизм для внедрения зависимостей и определения компонентов поддержки для веб-страниц, но они намного менее мощны, чем компоненты CDI.
Их можно определить с помощью @javax.faces.bean.ManagedBean
аннотации, которая принимает необязательный параметр имени. Это имя можно использовать для ссылки на bean-компонент со страниц JSF.
Область действия может быть применена к компоненту с использованием одной из различных областей, определенных в javax.faces.bean
пакете, которые включают запрос, сеанс, приложение, представление и настраиваемые области.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
Компоненты JSF не могут быть смешаны с другими видами bean-компонентов без какого-либо ручного кодирования.
CDI Beans
CDI - это среда управления компонентами и внедрения зависимостей, которая была выпущена как часть Java EE 6 и включает в себя полную, всеобъемлющую возможность управляемого компонента. Компоненты CDI намного более продвинуты и гибки, чем простые управляемые компоненты JSF. Они могут использовать перехватчики, область диалога, события, безопасное внедрение типов, декораторы, стереотипы и методы производителя.
Чтобы развернуть компоненты CDI, вы должны поместить файл с именем beans.xml в папку META-INF на пути к классам. Как только вы это сделаете, каждый bean-компонент в пакете станет bean-компонентом CDI. В CDI есть много функций, слишком много, чтобы здесь описывать, но в качестве краткого справочника по функциям, подобным JSF, вы можете определить объем компонента CDI, используя одну из областей, определенных в javax.enterprise.context
пакете (а именно, запрос, диалог , области сеанса и приложения). Если вы хотите использовать bean-компонент CDI со страницы JSF, вы можете дать ему имя с помощью javax.inject.Named
аннотации. Чтобы внедрить компонент в другой компонент, вы аннотируете поле javax.inject.Inject
аннотацией.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
Автоматическое внедрение, подобное определенному выше, можно контролировать с помощью квалификаторов, которые могут помочь сопоставить конкретный класс, который вы хотите внедрить. Если у вас несколько типов платежей, вы можете добавить квалификатор, указывающий, является ли он асинхронным или нет. Хотя вы можете использовать @Named
аннотацию в качестве квалификатора, вам не следует этого делать, поскольку она предназначена для раскрытия bean-компонентов в EL.
CDI обрабатывает внедрение bean-компонентов с несовпадающими областями видимости с помощью прокси. Из-за этого вы можете внедрить bean-компонент с ограниченным объемом запроса в bean-компонент с ограниченным сеансом, и ссылка будет по-прежнему действительна для каждого запроса, поскольку для каждого запроса прокси-сервер повторно подключается к активному экземпляру bean-компонента с ограниченным объемом запроса.
CDI также поддерживает перехватчики, события, новую область диалога и многие другие функции, что делает его гораздо лучшим выбором по сравнению с управляемыми компонентами JSF.
EJB
EJB-компоненты предшествуют bean-компонентам CDI и в чем-то похожи на компоненты CDI, а в других отношениях сильно отличаются. Прежде всего, разница между компонентами CDI и EJB заключается в том, что EJB:
- Транзакционный
- Удаленный или местный
- Возможность пассивировать bean-компоненты с отслеживанием состояния, освобождая ресурсы
- Возможность использовать таймеры
- Может быть асинхронным
Два типа EJB-компонентов называются без сохранения состояния и с сохранением состояния. EJB без сохранения состояния можно рассматривать как потокобезопасные одноразовые компоненты, которые не поддерживают какое-либо состояние между двумя веб-запросами. Компоненты EJB с отслеживанием состояния действительно сохраняют состояние и могут быть созданы и сидеть без дела столько времени, сколько они необходимы, пока они не будут удалены.
Определить EJB просто, вы просто добавляете к классу аннотацию javax.ejb.Stateless
или javax.ejb.Stateful
аннотацию.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
Компоненты без состояния должны иметь зависимую область видимости, в то время как сеансные компоненты с сохранением состояния могут иметь любую область. По умолчанию они транзакционные, но вы можете использовать аннотацию атрибута транзакции.
Хотя компоненты EJB и компоненты CDI очень различаются по функциям, написание кода для их интеграции очень похоже, поскольку компоненты CDI могут быть введены в EJB, а компоненты EJB могут быть введены в компоненты CDI. Нет необходимости делать какие-либо различия, вводя одно в другое. Опять же, CDI обрабатывает различные области с помощью прокси. Единственным исключением из этого правила является то, что CDI не поддерживает внедрение удаленных EJB-компонентов, но это можно реализовать, написав для него простой метод производителя.
javax.inject.Named
Аннотаций, а также любые Отборочные могут быть использованы на EJB , чтобы соответствовать его к точке впрыска.
Когда использовать какой фасоль
Как узнать, какой фасоль использовать? Просто.
Никогда не используйте управляемые bean-компоненты JSF, если вы не работаете в контейнере сервлетов и не хотите пытаться заставить CDI работать в Tomcat (хотя для этого есть несколько архетипов Maven, поэтому нет оправдания).
В общем, вам следует использовать компоненты CDI, если вам не нужны расширенные функции, доступные в EJB, такие как транзакционные функции. Вы можете написать свой собственный перехватчик, чтобы сделать компоненты CDI транзакционными, но сейчас проще использовать EJB, пока CDI не получит транзакционные компоненты CDI, которые уже не за горами. Если вы застряли в контейнере сервлетов и используете CDI, тогда либо рукописные транзакции, либо ваш собственный перехватчик транзакций - единственный вариант без EJB.
Если вам нужно использовать @ViewScoped
в CDI, вы должны
- используйте шов или модуль MyFaces CODI . просто добавьте один из них в свой путь к классам, и он
@ViewScoped
будет работать в CDI. MyFaces CODI имеет еще более надежную поддержку @ViewScoped
- используйте MyFaces CODI's
@ViewAccessScoped
, это расширение, написанное Apache поверх CDI, просто загрузите его и используйте @ViewAccessScoped
аннотацию вместо @ViewScoped
.
- Используйте CDI
@ConversationScoped
и сделайте его долгим. См. Здесь для получения дополнительной информации .
- Используйте аннотацию Omnifaces @ViewScoped
Некоторые детали украли отсюда .