O que é um EJB e o que ele faz?

151

Tentando aprender o que EJBsão grãos, o que significa que suas instâncias são gerenciadas em uma piscina, blá blá. Realmente não consigo entender bem.

Você pode me explicar o que eles realmente são (praticamente para um programador Java)? O que eles fazem? Quais são os seus propósitos? Por que realmente usá-los? (Por que não se apegar a isso POJO?) Talvez um exemplo de aplicativo?

Por favor, consulte apenas informações atualizadas EJB 3.1. Informações datadas sobre EJB podem ser enganosas.

Para iniciantes no aprendizado de EJB, observe:

Os EJB são baseados em objetos distribuídos ; isso se refere a partes de software em execução em várias máquinas (virtuais ou físicas) vinculadas por uma rede .

jacktrades
fonte

Respostas:

161

Por que realmente usá-los? (Por que não ficar com o POJO?)

Se você precisar de um componente que acesse o banco de dados, ou acesse outros recursos de conectividade / diretório, ou seja acessado de vários clientes, ou seja destinado a um serviço SOA, os EJBs hoje em dia são geralmente "maiores, mais fortes, mais rápidos (ou pelo menos mais escaláveis) e mais simples "que os POJOs. Eles são mais valiosos para atender um grande número de usuários pela rede corporativa ou pela Web e um pouco menos valiosos para aplicativos pequenos dentro de um departamento.

  1. Reutilizando / compartilhando a lógica entre vários aplicativos / clientes com o Loose Coupling.
    Os EJBs podem ser empacotados em seus próprios jarros, implantados e invocados de vários lugares. Eles são componentes comuns. É verdade que os POJOs podem ser (cuidadosamente!) Projetados como bibliotecas e empacotados como jarros. Mas os EJBs suportam acesso à rede local e remota - incluindo via interface java local, RMI transparente, mensagem assíncrona JMS e serviço da web SOAP / REST, economizando de dependências de jar de cortar e colar com várias implantações (inconsistentes?).
    Eles são muito úteis para criar serviços SOA. Quando usados ​​para acesso local, são POJOs (com serviços de contêiner gratuitos adicionados). O ato de projetar uma camada EJB separada promove um cuidado extra para maximizar o encapsulamento, o acoplamento e a coesão fracos e promove uma interface limpa (Fachada), protegendo os chamadores de modelos complexos de processamento e dados.

  2. Escalabilidade e confiabilidade Se você aplicar um grande número de solicitações de várias mensagens / processos / threads de chamada, elas serão distribuídas pelas instâncias EJB disponíveis no pool primeiro e depois na fila. Isso significa que, se o número de solicitações recebidas por segundo for maior do que o servidor pode suportar, degradaremos normalmente - sempre há algumas solicitações sendo processadas com eficiência e as solicitações em excesso são feitas para aguardar. Não atingimos o "colapso" do servidor - onde TODAS as solicitações experimentam um terrível tempo de resposta simultaneamente, além de o servidor tentar acessar mais recursos do que o hardware e o SO podem suportar e, portanto, travar. Os EJBs podem ser implantados em camadas separadas que podem ser agrupadas em cluster - isso fornece confiabilidade por meio de failover de um servidor para outro, além de hardware ser adicionado para escalar linearmente.

  3. Gerenciamento de Concorrência. O contêiner garante que as instâncias EJB sejam acessadas automaticamente com segurança (serialmente) por vários clientes. O contêiner gerencia o pool EJB, o pool de encadeamentos, a fila de chamada e executa automaticamente o bloqueio de gravação no nível do método (padrão) ou o bloqueio de leitura (através de @Lock (READ)). Isso protege os dados contra corrupção por meio de confrontos simultâneos de gravação e gravação e ajuda a leitura consistente dos dados, evitando conflitos de leitura e gravação.
    Isso é útil principalmente para os beans de sessão @Singleton, nos quais o bean está manipulando e compartilhando o estado comum entre os chamadores do cliente. Isso pode ser facilmente substituído para configurar manualmente ou controlar programaticamente cenários avançados para execução simultânea de código e acesso a dados.

  4. Manipulação automatizada de transações.
    Não faça nada e todos os seus métodos EJB são executados em uma transação JTA. Se você acessar um banco de dados usando JPA ou JDBC, ele será listado automaticamente na transação. O mesmo para invocações JMS e JCA. Especifique @TransactionAttribute (someTransactionMode) antes de um método para especificar se / como esse método específico participa da transação JTA, substituindo o modo padrão: "Necessário".

  5. Acesso a recursos / dependência muito simples via injeção.
    O contêiner procurará recursos e definirá referências de recursos como campos de instância no EJB: como conexões JDBC armazenadas JNDI, conexões / tópicos / filas JMS, outros EJBs, transações JTA, contextos de persistência do gerenciador de entidades JPA, unidades de persistência de fábrica do gerenciador de entidades JPA e Recursos do adaptador JCA. por exemplo, para configurar uma referência para outro EJB, uma transação JTA, um gerente de entidade JPA e uma fábrica e fila de conexão JMS:

    @Stateless
    public class MyAccountsBean {
    
        @EJB SomeOtherBeanClass someOtherBean;
        @Resource UserTransaction jtaTx;
        @PersistenceContext(unitName="AccountsPU") EntityManager em;
        @Resource QueueConnectionFactory accountsJMSfactory;
        @Resource Queue accountPaymentDestinationQueue;
    
        public List<Account> processAccounts(DepartmentId id) {
            // Use all of above instance variables with no additional setup.
            // They automatically partake in a (server coordinated) JTA transaction
        }
    }
    

    Um Servlet pode chamar esse bean localmente, simplesmente declarando uma variável de instância:

    @EJB MyAccountsBean accountsBean;    
    

    e então apenas chamando seus métodos conforme desejado.

  6. Interação inteligente com JPA. Por padrão, o EntityManager injetado como acima usa um contexto de persistência no escopo da transação. Isso é perfeito para beans de sessão sem estado. Quando um método EJB (sem estado) é chamado, um novo contexto de persistência é criado dentro da nova transação, todas as instâncias de objeto de entidade recuperadas / gravadas no DB são visíveis apenas nessa chamada de método e são isoladas de outros métodos. Porém, se outros EJBs sem estado são chamados pelo método, o contêiner se propaga e compartilha o mesmo PC com eles, para que as mesmas entidades sejam automaticamente compartilhadas de maneira consistente pelo PC na mesma transação.
    Se um bean de sessão @Stateful for declarado, será alcançada uma afinidade inteligente igual à JPA declarando o entityManager como um escopo estendido: @PersistentContent (unitName = "AccountsPU, type = EXTENDED). Isso existe durante toda a vida útil da sessão do bean, em várias chamadas e transações de bean, armazenando em cache cópias na memória de entidades de banco de dados recuperadas / gravadas anteriormente, para que elas não precisem ser recuperadas novamente.

  7. Gerenciamento do ciclo de vida. O ciclo de vida dos EJBs é gerenciado por contêiner. Conforme necessário, ele cria instâncias EJB, limpa e inicializa o estado do bean de sessão com estado, passiva e ativa e chama métodos de retorno de chamada do ciclo de vida, para que o código EJB possa participar de operações do ciclo de vida para adquirir e liberar recursos, ou executar outro comportamento de inicialização e desligamento. Ele também captura todas as exceções, registra-as, reverte as transações conforme necessário e lança novas exceções EJB ou @ApplicationExceptions conforme necessário.

  8. Gerenciamento de segurança. O controle de acesso baseado em funções para EJBs pode ser configurado por meio de uma anotação simples ou configuração XML. O servidor passa automaticamente os detalhes do usuário autenticado, juntamente com cada chamada, como contexto de segurança (principal e função da chamada). Ele garante que todas as regras do RBAC sejam aplicadas automaticamente para que os métodos não possam ser chamados ilegalmente pela função errada. Ele permite que os EJBs acessem facilmente os detalhes de usuário / função para verificação programática extra. Permite conectar processamento de segurança extra (ou mesmo ferramentas IAM) ao contêiner de maneira padrão.

  9. Padronização e Portabilidade. As implementações de EJB estão em conformidade com os padrões Java EE e convenções de codificação, promovendo qualidade e facilidade de entendimento e manutenção. Ele também promove a portabilidade de código para novos servidores de aplicativos de fornecedores, garantindo que todos eles suportem os mesmos recursos e comportamentos padrão e desencorajando os desenvolvedores a adotarem acidentalmente recursos proprietários
    de fornecedores não portáteis.

  10. O verdadeiro retrocesso: simplicidade. Tudo o que foi dito acima pode ser feito com código muito simplificado - usando configurações padrão para EJBs no Java EE 6 ou adicionando algumas anotações. A codificação de recursos corporativos / industriais em seus próprios POJOs seria muito mais volumosa, complexa e propensa a erros. Depois que você começa a codificar com EJBs, eles são fáceis de desenvolver e oferecem um ótimo conjunto de benefícios "free ride".

Na especificação EJB original de 10 anos atrás, os EJBs eram um grande problema de produtividade. Eles estavam inchados, precisavam de muitos artefatos de código e configuração e forneciam cerca de 2/3 dos benefícios acima. A maioria dos projetos da web não os utilizava. Mas isso mudou significativamente com 10 anos de ajustes, revisões, aprimoramento funcional e alinhamento do fluxo de desenvolvimento. No Java EE 6, eles fornecem força industrial de nível máximo e simplicidade de uso.

O que há para não gostar? :-) :-)

Glen Best
fonte
67

Um EJB é um componente Java, contendo lógica de negócios, implantada em um contêiner e que se beneficia dos serviços técnicos fornecidos pelo contêiner, geralmente de maneira declarativa, graças às anotações:

  • gerenciamento de transações: uma transação pode ser iniciada automaticamente antes que um método do EJB seja chamado e confirmado ou revertido assim que esse método retornar. Esse contexto transacional é propagado para chamadas para outros EJBs.
  • gerenciamento de segurança: pode-se verificar se o chamador possui as funções necessárias para executar o método.
  • injeção de dependência: outros EJBs ou recursos como um gerente de entidade JPA, uma fonte de dados JDBC etc. podem ser injetados no EJB.
  • simultaneidade: o contêiner garante que apenas um encadeamento de cada vez invoque um método da sua instância EJB.
  • distribuição: alguns EJBs podem ser chamados remotamente, de outra JVM.
  • failover e balanceamento de carga: os clientes remotos de seus EJBs podem ter suas chamadas automaticamente redirecionadas para outro servidor, se necessário.
  • gerenciamento de recursos: os beans com estado podem ser passivados automaticamente para o disco para limitar o consumo de memória do seu servidor.
  • ... Eu provavelmente esqueci alguns pontos.
JB Nizet
fonte
Quando você se refere à transação - você se refere à persistência?
jacktrades
6
Sim, mas não somente. Os contêineres EJB fornecem um gerenciador de transações JTA distribuído, suportando vários recursos em uma única transação. Você pode, por exemplo, atualizar alguns dados em um banco de dados e enviar algumas mensagens JMS, em uma única transação. Se algo falhasse, tudo seria revertido: o banco de dados é atualizado e as mensagens enviadas.
JB Nizet 13/10/12
O @JBNizet me desculpe por comentar sobre um encadeamento antigo, mas NÃO os frameworks EJB como o Spring estão fornecendo esses serviços que você mencionou. Eu não entendo a diferença
MoienGK
Os princípios básicos são os mesmos. Spring pegou idéias dos EJBs e vice-versa. Mas a API, a implementação, a maneira de implantar e alguns recursos são diferentes.
JB Nizet
@JB Nizet No padrão MVC, onde você colocaria os EJBs em geral? Eu diria que eles pertencem à camada Model, embora eu conheça muitas pessoas que dizem que são controladoras. Se o EJB contiver lógica de negócios (você disse que sim), eles serão a camada do modelo por definição.
user107986
22

Espero que este documento da Oracle ajude alguém como eu a entender o tópico do EJB de uma maneira simples.

O que é um bean corporativo? Escrito na linguagem de programação Java, um enterprise bean é um componente do lado do servidor que encapsula a lógica de negócios de um aplicativo. A lógica de negócios é o código que cumpre o objetivo do aplicativo. Em um aplicativo de controle de inventário, por exemplo, os beans corporativos podem implementar a lógica de negócios em métodos chamados checkInventoryLevel e orderProduct. Invocando esses métodos, os clientes podem acessar os serviços de inventário fornecidos pelo aplicativo.

Benefícios dos beans corporativos Por várias razões, os beans corporativos simplificam o desenvolvimento de aplicativos grandes e distribuídos. Primeiro, como o contêiner EJB fornece serviços no nível do sistema para beans corporativos, o desenvolvedor do bean pode se concentrar na solução de problemas de negócios. O contêiner EJB, em vez do desenvolvedor do bean, é responsável pelos serviços no nível do sistema, como gerenciamento de transações e autorização de segurança.

Segundo, como os beans, e não os clientes, contêm a lógica de negócios do aplicativo, o desenvolvedor do cliente pode se concentrar na apresentação do cliente. O desenvolvedor do cliente não precisa codificar as rotinas que implementam regras de negócios ou acessam bancos de dados. Como resultado, os clientes são mais finos, um benefício particularmente importante para clientes executados em dispositivos pequenos.

Terceiro, como os beans corporativos são componentes portáteis, o montador de aplicativos pode criar novos aplicativos a partir dos beans existentes. Esses aplicativos podem ser executados em qualquer servidor Java EE compatível, desde que eles usem as APIs padrão.

Quando usar beans corporativos Você deve considerar o uso de beans corporativos se o seu aplicativo tiver algum dos seguintes requisitos:

O aplicativo deve ser escalável. Para acomodar um número crescente de usuários, pode ser necessário distribuir os componentes de um aplicativo em várias máquinas. Não apenas os beans corporativos de um aplicativo podem ser executados em máquinas diferentes, mas também sua localização permanecerá transparente para os clientes.

As transações devem garantir a integridade dos dados. Os beans corporativos suportam transações, os mecanismos que gerenciam o acesso simultâneo de objetos compartilhados.

O aplicativo terá uma variedade de clientes. Com apenas algumas linhas de código, os clientes remotos podem localizar facilmente enterprise beans. Esses clientes podem ser magros, variados e numerosos.

Tesfa Zelalem
fonte
3

A questão que mais me interessa é como e onde posso usá-las. Para entender isso, precisamos primeiro ver quais tipos de EJBs existem. Existem 2 grandes categorias:

  1. Beans de sessão
  2. Beans acionados por mensagens

Vamos considerar os Session Beans. Eles são de 3 tipos:

  1. Com estado - esses componentes mantêm o estado e são específicos para um cliente em várias solicitações. Veja isso como uma sessão. O uso imediato a que esses itens podem ser usados ​​é carrinhos de compras ou outro tipo de sessão (sessão de login e assim por diante)
  2. Sem estado - são componentes independentes que não persistem informações entre solicitações, mas são exclusivos para o usuário. Uso imediato que vem à mente - Classes de serviço na camada de serviço . Imagine OrderService. Outro grande uso para isso é expor serviços da web. Novamente, isso está na camada Serviço ou é totalmente separado.
  3. Singleton - esses são os beans que existem por aplicativo e são criados uma vez e podem ser reutilizados / acessados ​​várias vezes. Imediatamente o Configurationcomponente vem à mente - onde você pode armazenar configurações no nível do aplicativo e acessá-las quando precisar delas de qualquer lugar.

Agora, o restante dos recursos ou recursos pode ser usado em várias camadas em qualquer situação:

  • Segurança - você pode verificar as permissões com uma anotação no método chamado. Isso pode acontecer na camada de serviço e no controlador, se você desejar.
  • Gerenciamento de transações - esse é o candidato óbvio na camada Serviço ou na camada Persistência
  • Injeção de Dependência - novamente será usada em qualquer lugar

Um grande uso nos tempos modernos são os chamados microsserviços e arquiteturas orientadas a serviços. Você pode empacotar alguns componentes da lógica de negócios como EJBs e distribuí-los por toda a organização, para serem usados ​​por vários clientes (por cliente, aqui eu quero dizer outros aplicativos de back-end).

E assim por diante. Agora, a grande desvantagem é que você se torna muito dependente do contêiner EJB e, embora possa alternar entre duas implementações de referência, não poderá mudar para algo mais leve - o Tomcat, por exemplo. Mas por que você quer sacrificar todos os benefícios?

ACV
fonte