На самом деле это очень хороший вопрос.
Я использую тот же самый стек (Java EE 7, Glassfish 4, JSF 2.2, EclipseLink JPA, EJB 3.1) для 70% своей деятельности по разработке, и я часто разрабатываю собственные сайты электронной коммерции, поэтому я знаком с дизайном покупок тележки.
Два подхода, которым я следовал (прежде чем окончательно выбрать один из двух):
- Сессионный EJB с отслеживанием состояния, реализующий
@Remote
простой интерфейс Java, который определяет логику деловой активности.
SessionScoped
ManagedBean и EJB без сохранения состояния, реализующие @Local
интерфейс, который определяет бизнес-логику.
Лично я начал с первого подхода, но недавно перешел на второй. Я объясню почему, позже в этом ответе.
Этот первый подход действительно прост. Вам просто нужен простой интерфейс с аннотацией @Remote
и @Stateful
Session Bean, реализующим его. Затем в вашем поддерживающем компоненте вы можете внедрить интерфейс через CDI, используя аннотацию @EJB
вместо аннотации @Inject
, чтобы использовать все полезные функции EJB-инъекций, такие как объединение. Для вашей тележки я бы создал:
1) интерфейс с именем ShoppingCart.java:
@Remote
public interface ShoppingCart{
public void init(Integer id);
public void addToCart(String product);
}
2) EJB сеанса с отслеживанием состояния с именем ShoppingCartImpl.java, реализующий интерфейс ShoppingCart.java.
@Stateful
public class ShoppingCartImpl implements ShoppingCart{
private Integer uid;
private ArrayList<String> products;
@PostConstruct
private void create(){
producs = new ArrayList<String>();
}
@Override
public void init(Integer id){
if(id==null){
uid = id;
}
}
@Override
public void addToCart(String product){
if(product!=null){
products.add(product);
}
}
}
Клиентский класс может получить доступ к сессионному компоненту Statefull с помощью CDI через аннотацию @EJB.
public class ShoppingCartClient {
@EJB
private static ShoppingCart cart;
// your methods here, using the ShoppingCart interface
}
Фактическая «связь» между физическим покупателем и его экземпляром экземпляра реализации ShoppingCart гарантирована, поскольку каждый клиент связан с новым экземпляром сеансового компонента с отслеживанием состояния. С точки зрения клиента кажется, что бизнес-методы выполняются локально, хотя в сеансовом компоненте они выполняются удаленно. Для записей ... Oracle в своих собственных руководствах предлагает этот подход.
МОЙ ПРЕДПОЧТИТЕЛЬНЫЙ ПОДХОД
Я предпочитаю использовать JSF-компонент поддержки SessionScoped, представляющий код, и использовать EJB без сохранения состояния для доступа к необходимой бизнес-логике. В этом случае тоже нужен интерфейс, но его можно сделать локальным, изменив код примерно так:
1) Локальный интерфейс Java
@Local
public interface ShoppingCart{
public void doSomething(List<Product> list);
}
2) EJB без сохранения состояния
@Stateless
public class ShoppingCartImpl implements ShoppingCart{
@Override
public void doSomething(List<Product> list){
// persistence, tax calculation, etc
}
}
3) Бин с ограничением сеанса JSF
@ManagedBean
@SessionScoped
public class CartBean {
private List<Product> products = new ArrayList<Product>();
public void add(Product product) {
products.add(product);
}
public void remove(Product product) {
products.remove(product);
}
public List<Product> getProducts() {
return products;
}
}
Второй подход имеет следующие преимущества:
- EJB без сохранения состояния быстрее, чем EJB с отслеживанием состояния
- Создание пула поддержки EJB без сохранения состояния
Объем памяти такой же, как и в первом случае, поскольку JSF хранит управляемые компоненты с привязкой к сеансу точно так же, как и сеансовые компоненты с отслеживанием состояния.
Компоненты EJB с отслеживанием состояния подходят, если вы хотите иметь возможность использовать его где-то еще или делиться ими между разными веб-приложениями.
person
elbuild
schedule
09.01.2014