Перш за все, дозвольте мені зробити пояснення:
Визначення керованої квасолі : загалом керована квасоля - це об'єкт, яким її життєвий цикл (будівництво, знищення тощо) керує контейнер.
У Java ee у нас є багато контейнерів, які керують життєвим циклом їх об'єктів, як контейнер JSF, контейнер EJB, контейнер CDI, контейнер Servlet тощо.
Усі ці контейнери працюють на зразок незалежних, вони завантажуються в ініціалізацію сервера додатків і сканують класи всіх артефактів, включаючи jar, ejb-jar, файли війни та вух у час розгортання, збирають і зберігають деякі метадані про них, тоді коли вам потрібен об'єкт класу під час виконання вони дадуть вам екземпляри цих класів, і після закінчення завдання вони знищать їх.
Тож можна сказати, що у нас є:
- JSF керували квасолею
- CDI керували квасолею
- EJB керувала квасолею
- І навіть сервлетами керують боби, тому що вони інстанціровані і знищені контейнером, який є контейнером із сервлетами.
Отже, коли ви бачите слово керованого квасолі, вам слід запитати про його контекст або тип. (JSF, CDI, EJB тощо)
Тоді ви можете запитати, чому у нас багато таких контейнерів: хлопці AFAIK, Java EE хотіли мати рамку введення залежності, але вони не змогли зібрати всі вимоги в одну специфікацію, оскільки вони не могли передбачити майбутні вимоги, і вони зробили EJB 1.0 і потім 2.0, а потім 3.0 і тепер 3.1, але ціль EJB була лише для деяких вимог (транзакція, модель розподілених компонентів тощо).
У той же час (паралельно) вони зрозуміли, що їм також потрібно підтримувати JSF, тоді вони зробили боби з JSF, які керували JSF, та іншу ємність для бобів JSF, і вважали це зрілим контейнером DI, але все-таки це не повний та зрілий контейнер.
Після цього Гевін Кінг та деякі інші приємні хлопці;) зробили CDI, який є найбільш зрілим контейнером DI, який я бачив. CDI (натхненний Seam2, Guice та Spring) був створений, щоб заповнити проміжок між JSF та EJB та багатьма іншими корисними речами, такими як ін'єкція pojo, методи виробника, перехоплювачі, декоратори, SPI інтеграції, дуже гнучкі тощо, і це навіть може зробити те, що роблять EJB та JSF з бобами, то ми можемо мати лише один зрілий та потужний контейнер DI. Але з якоїсь відсталої сумісності та політичних причин хлопці Java EE хочуть їх зберегти !!!
Тут ви можете знайти різницю та використовувати випадки для кожного з цих типів:
Керовані квасолею JSF, квасолею CDI та EJB
Спочатку JSF був розроблений з власним керованим механізмом введення бобів та залежностей, який було вдосконалено для JSF 2.0, щоб включати боби на основі анотації. Коли CDI був випущений з Java EE 6, він розглядався як керована рамка для цієї платформи, і, звичайно, EJB застаріли, і все це було майже протягом десяти років.
Проблема, звичайно, полягає в тому, щоб знати, який з них використовувати та коли їх використовувати.
Почнемо з найпростіших бобів, керованих JSF.
Керовані квасолею JSF
Якщо коротко, не використовуйте їх, якщо ви розробляєте для Java EE 6 і використовуєте CDI. Вони забезпечують простий механізм введення залежності та визначення резервних бобів для веб-сторінок, але вони набагато менш потужні, ніж CDI.
Вони можуть бути визначені за допомогою @javax.faces.bean.ManagedBean
примітки, яка приймає необов'язковий параметр імені. Ця назва може використовуватися для посилання на квасоля зі сторінок JSF.
Область застосування може бути застосована до квасолі за допомогою одного з різних областей, визначених у javax.faces.bean
пакеті, які включають запит, сеанс, додаток, перегляд та спеціальні області застосування.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
Боби JSF не можна змішувати з іншими видами квасолі без якогось ручного кодування.
CDI квасоля
CDI - це система управління бобами та введення залежностей, яка була випущена у складі Java EE 6, і вона включає в себе повне, всебічне управління квасолею. CDI-боби набагато досконаліші та гнучкіші, ніж прості боби, керовані JSF. Вони можуть використовувати перехоплювачі, сферу розмови, події, тип безпечної ін'єкції, декоратори, стереотипи та методи виробників.
Для розгортання бобів CDI потрібно розмістити файл, який називається beans.xml, у папці META-INF на classpath. Як тільки ви це зробите, то кожна квасоля в упаковці стає квасолею CDI. У CDI є багато функцій, тут занадто багато, щоб охопити тут, але як швидке посилання на функції, схожі на JSF, ви можете визначити сферу використання квасолі CDI, використовуючи одну з областей, визначених у javax.enterprise.context
пакеті (а саме: запит, розмова , сфери сеансу та програми). Якщо ви хочете використовувати CDI-боб зі сторінки JSF, ви можете дати йому ім'я за допомогою javax.inject.Named
примітки. Щоб ввести квасоля в інший квасоля, ви коментуєте поле javax.inject.Inject
анотацією.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
Автоматичне введення, подібне до визначеного вище, можна контролювати за допомогою кваліфікаційних кваліфікаторів, які допоможуть відповідати конкретному класу, який потрібно вводити. Якщо у вас є кілька типів платежів, ви можете додати кваліфікатор, чи він асинхронний чи ні. Хоча ви можете використовувати @Named
анотацію як класифікатор, не слід, оскільки це передбачено для експонування бобів у EL.
CDI обробляє ін'єкцію квасолі з невідповідними сферами застосування проксі. Через це ви можете ввести бій, на якому розміщено запит, у бін, що охоплює сеанс, і посилання все одно буде дійсною для кожного запиту, оскільки для кожного запиту проксі повторно підключається до живого екземпляра запиту.
CDI також має підтримку перехоплювачів, подій, нову сферу розмови та багато інших функцій, що робить його набагато кращим вибором щодо керованих JSF бобів.
EJB
EJB передують квасолі CDI і подекуди схожі на CDI-боби, а іншими способами сильно відрізняються. Перш за все, різниця між CDI бобами та EJB полягає в тому, що EJB:
- Трансакційні
- Віддалений або локальний
- Здатний пасивувати величні боби, звільняючи ресурси
- Можливість використовувати таймери
- Може бути асинхронним
Два типи 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 , щоб відповідати його до точки уприскування.
Коли використовувати який квасоля
Як ви знаєте, коли вживати який боб? Простий.
Ніколи не використовуйте керовані JSF боби, якщо ви не працюєте в контейнері сервлетів і не хочете намагатися отримати CDI, що працює в Tomcat (хоча для цього є деякі архетипи Maven, тому немає виправдання).
Загалом, ви повинні використовувати CDI-боби, якщо вам не потрібна розширена функціональність, доступна в EJB, таких як транзакційні функції. Ви можете написати власний перехоплювач, щоб зробити CDI боби транзакційними, але наразі простіше використовувати EJB, поки CDI не отримає транзакційні CDI-боби, які знаходяться недалеко від кута. Якщо ви застрягли в контейнері сервлетів і використовуєте CDI, то або рукописний транзакцій, або ваш власний перехоплювач транзакцій - єдиний варіант без EJB.
Якщо вам потрібно використовувати @ViewScoped
CDI, вам слід
- використовувати шви граней або модуль MyFaces CODI . просто додайте одну з них на свій класний шлях і
@ViewScoped
буде працювати в CDI. MyFaces CODI має ще більш надійну підтримку @ViewScoped
- використовуйте CODI MyFaces
@ViewAccessScoped
, це розширення, написане Apache на CDI поверх CDI, просто завантажте його та @ViewAccessScoped
замість цього використовуйте анотацію @ViewScoped
.
- Використовуйте CDI
@ConversationScoped
і зробіть його тривалим. Дивіться тут для отримання додаткової інформації .
- Використовуйте примітки Omniface @ViewScoped
Деякі частини розкрадаються звідси .