На самом деле это очень хороший вопрос.
Я использую тот же точный стек (Java EE 7, Glassfish 4, JSF 2.2, EclipseLink JPA, EJB 3.1) для 70% моей деятельности по развитию, и я часто разрабатываю пользовательские сайты электронной коммерции, поэтому я знаком с дизайн тележек для покупок.
двух подходов я следовал (прежде чем окончательно решить одну из двух):
- Stateful Session EJB, реализующего простой интерфейс
@Remote
Java, который определяет businness логику
SessionScoped
ManagedBean и Stateless 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) Stateful Session 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 в своих собственных учебниках предлагает такой подход.
предпочтительную ПОДХОД
Мой предпочтительный подход заключается в использовании бэк боб SessionScoped JSF, представляющий код, и используя Stateless EJB, чтобы получить доступ к необходимой бизнес-логики. Интерфейс необходим в этом случае, но это может быть сделано местное, изменение кода что-то вроде этого:
1) Java Локальный интерфейс
@Local
public interface ShoppingCart{
public void doSomething(List<Product> list);
}
2) Stateless EJB
@Stateless
public class ShoppingCartImpl implements ShoppingCart{
@Override
public void doSomething(List<Product> list){
// persistence, tax calculation, etc
}
}
3) JSF Session Bean Scoped
@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;
}
}
Второй подход имеет следующие преимущества:
- Stateless EJB быстрее затем Stateful EJB
- Stateless EJB поддержка пулы дизайн
Объем памяти такой же, как в первом случае, так как JSF хранит сеанс контекстными управляемые компоненты таким же образом Stateful Сессионные бобы хранятся.
Stateful EJB подходят, если вы хотите использовать его где-то в другом месте или делиться ими между различными webapp.
Рассмотрите этот сценарий: у вас есть дополнительное приложение для Android, подключающееся к вашему приложению с помощью 'JAX-RS', и вам нужна корзина для покупок. Услуги такие же, как и в веб-приложении JSF. Используете ли вы SFSB или SLSB в корзине покупок? –
Я бы использовал SLSB для мобильного приложения. Я разработал мобильные приложения, которые взаимодействуют с barebone serlvets, просматривая простые ответы JSON, созданные с использованием SLSB, вводимого через CDI (аннотации @EJB). – elbuild
В вашем первом примере подхода вы храните «ShoppingCartClient» в качестве атрибута в объекте HttpSession, правильно? –