Quando é necessário ou conveniente usar Spring ou EJB3 ou todos eles juntos?

Estou um pouco confuso com o uso misto de JSF2 + Spring + EJB3 ou qualquer combinação deles. Eu sei que uma das principais características do Spring é a injeção de dependência, mas com beans gerenciados pelo JSF eu posso usar @ManagedBean e @ManagedProperty e obter a funcionalidade de injeção de dependência. Com o EJB3, estou ainda mais confuso sobre quando usá-lo junto com o JSF ou se existe um motivo para usá-lo.

Então, em que tipo de situação seria uma boa idéia usar o Spring + JSF2 ou o EJB3 + JSF2?

Até agora, criei apenas alguns pequenos aplicativos da web usando apenas o JSF2 e nunca precisei usar o Spring ou o EJB3. No entanto, estou vendo em muitos lugares que as pessoas estão trabalhando com todas essas coisas juntas.

Primeiro de tudo, Spring e EJB (+ JTA) são tecnologias concorrentes e geralmente não devem ser usados ​​juntos no mesmo aplicativo. Escolha um ou outro. Mola ou EJB (+ JTA). Não vou lhe dizer qual escolher, vou contar apenas um pouco da história e dos fatos para facilitar a decisão.


O principal problema que eles estão tentando resolver é fornecer uma API de camada de serviço de negócios com gerenciamento automático de transactions. Imagine que você precise triggersr várias consultas SQL para executar uma única tarefa de negócios (por exemplo, fazer um pedido), e uma delas falhou, então você obviamente gostaria que tudo fosse revertido, para que o database permanecesse no mesmo estado como era antes, como se nada tivesse acontecido. Se você não fizesse uso de transactions, o database seria deixado em um estado inválido porque o primeiro grupo de consultas realmente foi bem-sucedido.

Se você estiver familiarizado com o JDBC básico, então você deve saber que isso pode ser alcançado desativando o commit() automático na conexão, em seguida, triggersndo as consultas em sequência e executando commit() na mesma try em que catch (SQLException) rollback() é executado. Isto é no entanto bastante tedioso para implementar toda vez.

Com Spring e EJB (+ JTA), uma única chamada de método de serviço de negócios (sem estado) é contada por padrão de forma transparente como uma única transação completa. Dessa forma, você não precisa se preocupar com o gerenciamento de transactions. Você não precisa criar manualmente EntityManagerFactory nem chamar explicitamente em.getTransaction().begin() e fazer o mesmo quando estiver em.getTransaction().begin() lógica do serviço de negócios de forma compacta em uma class de bean de apoio do JSF e / ou usando RESOURCE_LOCAL de JTA na JPA. Você poderia, por exemplo, ter apenas a seguinte class EJB utilizando o JPA:

 @Stateless public class OrderService { @PersistenceContext private EntityManager em; @EJB private ProductService productService; public void placeOrder(Order newOrder) { for (Product orderedproduct : newOrder.getProducts()) { productService.updateQuantity(orderedproduct); } em.persist(newOrder); } } 

Se você tiver um @EJB private OrderService orderService; no seu bean de apoio do JSF e invoque o orderService.placeOrder(newOrder); no método de ação, uma única transação completa será executada. Se, por exemplo, uma das chamadas updateQuantity() ou persist() falhar com uma exceção, ela reverterá as chamadas updateQuantity() executadas até o momento e deixará o database em um estado limpo e nítido. Naturalmente, você poderia capturar essa exceção em seu bean de apoio do JSF e exibir uma mensagem de faces ou algo assim.

Notou-se que “Spring” é um framework bastante grande que não apenas compete com o EJB, mas também com o CDI e o JPA. Anteriormente, durante as idades J2EE escuras, quando o EJB 2.x era extremamente terrível de implementar (o exemplo acima de EJB 3.x OrderService no EJB 2.x exigiria pelo menos 5 vezes mais código e algum código XML). O Spring ofereceu uma alternativa muito melhor que exigia menos código Java (mas ainda muitos códigos XML). O J2EE / EJB2 aprendeu as lições do Spring e veio com o Java EE 5, que oferece uma nova API do EJB3, que é ainda mais fluida do que o Spring e não exigiu nenhum XML.

A Spring também oferece IoC / DI (inversão de controle; injeção de dependência) fora da checkbox. Isso foi durante a era do J2EE configurado pelo XML, que pode ser bastante exagerado. Atualmente, o Spring também usa annotations, mas ainda é necessário algum XML. Desde o Java EE 6, depois de ter aprendido as lições da Spring, o CDI é oferecido com a mesma funcionalidade DI, mas sem necessidade de XML. Com Spring DI @Component / @Autowired e CDI @Named / @Inject você pode obter o mesmo que o JSF com @ManagedBean / @ManagedProperty , mas o Spring DI e o CDI oferecem muitas outras vantagens: você pode, por exemplo, gravar interceptores em pré -processamento ou pós-processamento do bean gerenciado criação / destruição ou uma chamada de método de bean gerenciado, você pode criar escopos personalizados, produtores e consumidores, você pode injetar uma instância de escopo mais restrito em uma instância de escopo mais amplo, etc.

A Spring também oferece MVC que essencialmente compete no JSF. Não faz sentido misturar o JSF com o Spring MVC. Além disso, o Spring também oferece dados que são essencialmente uma camada extra de abstração sobre o JPA, minimizando ainda mais o texto padrão do DAO (mas que essencialmente não representa a camada de serviço de negócios como um todo).

Veja também:

  • O que exatamente é o Java EE?
  • Controlador JSF, Serviço e DAO
  • @Stateless beans versus @Stateful beans

Não há uma resposta fácil aqui, pois a spring é muitas coisas.

Em um nível muito alto, o Spring compete com o Java EE, o que significa que você usaria um deles como uma estrutura de pilha completa.

Em um nível mais refinado, o contêiner Spring IoC e o Spring Beans competem com a combinação de CDI e EJB no Java EE.

Quanto à camada web, o Spring MVC compete com o JSF. Alguns Spring xyzTemplate competem com as interfaces JPA (ambos podem usar, por exemplo, o Hibernate como a implementação deles).

É possível misturar e combinar; Por exemplo, use os beans CDI e EJB com Spring MVC, ou use Spring Beans com JSF.

Você normalmente não usará 2 técnicos concorrentes diretamente. Spring beans + CDI + EJB no mesmo aplicativo, ou Spring MVC + JSF é bobagem.