JavaRush /Blogue Java /Random-PT /Apresentando o EJB
Анзор Кармов
Nível 31
Санкт-Петербург

Apresentando o EJB

Publicado no grupo Random-PT
Neste artigo veremos EJB – Enterprise JavaBeans. Esta tecnologia faz parte da especificação Java EE. Iremos abordar questões como:
  • o que é EJB;
  • qual é a história do EJB;
  • que tipos de EJB existem?
Também escreveremos um pequeno aplicativo HelloWorld usando EJB e servlets. Apresentando EJB - 1Este artigo será útil para leitores que se familiarizaram com Java SE e estão começando a aprender Java EE. Para compreender totalmente a parte prática deste artigo, é recomendável que você leia primeiro o artigo “ Configurando o ambiente local ”.

Uma Breve História do EJB

Em 1996, quando o autor deste artigo tinha 5 anos, Java já era popular entre os desenvolvedores. A razão para isso foi a API amigável, coleta automática de lixo, etc. Java foi amplamente utilizado em sistemas responsáveis ​​pelo backend. Porém, apesar de todas as delícias da linguagem, os programadores da época precisavam de certas funcionalidades que ainda não estavam implementadas no JDK. Essas necessidades eram:
  • garantir a persistência dos dados;
  • integridade da transação
  • acesso competitivo aos dados (controle multithreading);
  • e provavelmente outra coisa.
Tudo isso levou a um crescimento natural na população de bibliotecas fechadas, auto-escritas e criadas localmente. Em outras palavras, todos atenderam às suas necessidades da melhor maneira possível. Isso até a IBM lançar o slogan “Todos deveriam atender às suas necessidades da mesma maneira” e lançar a especificação Enterprise Java Bean (EJB) em 1997. Foi isso que permitiu unificar o processo de desenvolvimento e levar para o framework a solução de problemas típicos (descritos acima como necessidades). A Sun vem adaptando a ideia da IBM há 2 anos e, em 1999, lançou a especificação EJB 1.0. Foi assim que nasceu a tecnologia, que será discutida mais adiante de forma mais aplicada.

O que é EJB

EJB, em certo sentido, é um termo coletivo que, dependendo do contexto, pode significar a própria tecnologia Enterprise JavaBeans em geral ou algum componente de software Enterprise JavaBean específico (bean) que faz parte da tecnologia EJB. A definição de EJB como tecnologia é dada na Wikipedia: Enterprise JavaBeans (também frequentemente usado como abreviatura EJB) é uma especificação de uma tecnologia para escrever e suportar componentes de servidor contendo lógica de negócios. Faz parte do Java EE. Essa tecnologia normalmente é usada quando a lógica de negócios requer pelo menos um dos seguintes serviços e, geralmente, todos eles:
  • suporte para persistência de dados: os dados devem estar seguros mesmo após a interrupção do programa. Na maioria das vezes conseguido usando um banco de dados;
  • suporte para transações distribuídas;
  • suporte para modificação paralela de dados e multithreading;
  • suporte a eventos;
  • suporte para nomenclatura e diretório (JNDI);
  • segurança e restrição de acesso aos dados;
  • suporte para instalação automatizada no servidor de aplicativos;
  • acesso remoto.
Os serviços listados acima são uma vantagem indiscutível da tecnologia EJB. Outra vantagem é que tudo listado acima funciona imediatamente. Aqueles. o programador não precisa pensar em apoiar transações distribuídas. O programador só precisa pensar na lógica de negócios que está tentando implementar no momento. Um EJB como componente de software específico é uma classe Java com uma ou mais anotações da especificação EJB que contém parte da lógica de negócios do aplicativo. As anotações da especificação EJB fornecem à classe marcada certos poderes, poderes e superpoderes. Leia mais sobre isso abaixo.

Tipos EJB

Vamos resumir. Um EJB é uma classe Java regular marcada com uma das anotações especiais. Essas classes são chamadas de beans. Dependendo da anotação com a qual a classe está marcada, ela será representativa de um ou outro tipo de EJB (beans). Existem três tipos principais de feijão:
  • Beans orientados a mensagens (beans orientados a mensagens);
  • Entity Beans - definidos na especificação JPA (Java Persistence API) e utilizados para armazenar dados;
  • Feijão de Sessão.
Os últimos (beans de sessão) são divididos em vários subtipos:
  • apátrida (sem estado);
  • stateful (com suporte para o estado atual da sessão);
  • singleton (um objeto para toda a aplicação; a partir do EJB 3.1).
Apresentando EJB-2A seguir veremos cada tipo de feijão com mais detalhes.

Feijões de Sessão

Session Beans, ou beans de sessão, são um tipo específico de bean. Eles encapsulam a lógica de negócios que o cliente pode invocar programaticamente chamando os métodos do bean. Uma chamada de método pode fazer:
  • localmente, por outra classe na mesma JVM que o bean de sessão;
  • remotamente, pela rede, a partir de outra JVM, utilizando a tecnologia Java RMI (Remote Method Invocation).
A palavra “sessão” implica que o bean está disponível apenas enquanto o servidor está executando uma tarefa específica e é irremediavelmente destruído no caso de falha ou desligamento do servidor. O ciclo de vida de uma instância de bean de sessão é controlado por um contêiner EJB (você pode ler mais sobre contêineres EJB na primeira aula da série ). Beans de sessão sem estado não armazenam informações sobre seu estado. Este tipo de componente pode ser utilizado por diversos clientes. Beans sem estado são usados ​​para implementar processos de negócios que podem ser concluídos em uma operação. Por exemplo, verificar o histórico de crédito dos clientes. Como uma única instância de bean pode ser usada por vários clientes, o desenvolvedor deve fornecer acesso thread-safe aos dados do bean. Criar um bean deste tipo (assim como todos os outros beans de sessão) é bastante simples. Esta é uma classe Java regular com uma anotação @Stateless. Vamos dar um exemplo abaixo:
import javax.ejb.Stateless;

@Stateless
public class StatelessEjbExample {
    public String sayHi() {
        return "Hi, I'm Stateless EJB!";
    }
}
Os beans de sessão que suportam o estado atual da sessão (Stateful) retêm informações sobre seu estado entre chamadas do mesmo cliente e encerram sua existência mediante uma solicitação explícita do cliente. Isto é conseguido devido ao fato de que os stateful beans são únicos para cada cliente. Um exemplo de tarefa pela qual este tipo de bean pode ser responsável é manter o carrinho de compras de uma loja online atualizado para cada usuário. O ciclo de vida desses beans é gerenciado pelo contêiner EJB. Esses beans também são destruídos quando o cliente é encerrado. Esses feijões também são bastante fáceis de criar. Esta é uma classe Java marcada com a anotação Stateful. Exemplo abaixo:
import javax.ejb.Stateful;

@Stateful
public class StatefulEjbExample {
    public String sayHi() {
        return "Hi, I,m Stateful EJB";
    }
}
Os beans de sessão singleton são iniciados uma vez durante a vida útil do aplicativo e existem durante toda a vida útil do aplicativo. Esses beans são projetados para situações nas quais um estado deve ser compartilhado entre todos os clientes. Assim como os beans sem estado, nos beans autônomos o desenvolvedor precisa garantir que o bean tenha um ambiente seguro para threads. Vamos dar um exemplo de bean Singleton, que é tão fácil de criar quanto seus equivalentes discutidos acima. É fácil adivinhar que esta é uma classe Java com a anotação @Singleton. Porém, neste caso você precisa ter cuidado. Existem duas anotações, idênticas em sintaxe, mas com finalidades diferentes e localizadas em pacotes diferentes:
  • javax.ejb.Singleton
  • javax.inject.Singleton
Para criar um EJB, você deve usar a anotação do arquivo javax.ejb. Exemplo abaixo:
import javax.ejb.Singleton;

@Singleton
public class SingletonEjbExample {
    public String sayHi() {
        return "Hi, I'm Singleton EJB!";
    }
}

Feijões orientados por mensagens

Message Driven Beans, ou MDBs, ou beans acionados por mensagens, implementam alguma lógica de negócios, como beans de sessão. Mas, diferentemente de seus parentes, o MDB tem uma diferença importante. Os clientes nunca chamam métodos MDB diretamente. Esses beans geralmente atuam como ouvintes de mensagens JMS (Java Message Service) e servem para organizar a troca assíncrona de mensagens entre partes do sistema. Um exemplo de tal mensagem seria uma solicitação de entrega de estoque de um sistema automatizado de varejo para um sistema de gerenciamento de suprimentos. Abaixo está um exemplo de um bean MDB. Diferentemente dos beans de sessão, sua criação é um pouco mais interessante:
import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "jms/TestQueue")
public class MessageDrivenEjbExample implements MessageListener {

    @Resource
    private MessageDrivenContext messageDrivenContext;

    public void onMessage(Message message) {
        try {
            if (message instanceof TextMessage) {
                TextMessage msg = (TextMessage) message;
                msg.getText();
            }
        } catch (JMSException e) {
            messageDrivenContext.setRollbackOnly();
        }
    }

}
A anotação MessageDriventorna nossa classe MDB um bean. Dentro da anotação, usando JNDI (leia sobre JNDI aqui ), é determinado o nome da distribuição JMS, da qual nossa classe se torna ouvinte. Além disso, nossa classe implementa a interface MessageListenere seu método onMessage. Este método será chamado quando chegar alguma mensagem da fila/distribuição com o nome definido dentro da anotação MessageDriven.

Beans de entidade

Parte da tecnologia EJB é a especificação JPA. JPA, ou Java Persistence API, é uma especificação que fornece Mapeamento Objeto-Relacional (ORM) de objetos Java (Entity beans) e fornece uma API para armazenar, recuperar e gerenciar tais objetos. JPA permite representar dados de um banco de dados como objetos Java, bem como salvar objetos Java como registros no banco de dados. Nem toda classe pode atuar como tal objeto, mas os beans de entidade. Entity Bean é uma classe Java que representa uma tabela em um banco de dados. A exibição (mapeamento) é obtida através do uso de anotações especiais. Com a ajuda deles, uma classe Java é comparada com uma tabela no banco de dados, assim como os campos de uma classe Java são comparados com os campos de uma tabela de banco de dados. Aqui está um exemplo de bean Entity, com comentários no código:
@Entity // Делает данный класс Entity бином
@Table(name = "employee") // "Связывает" данный класс с таблицей employee в БД
public class Employee implements Serializable {

    @Id // Говорит о том, что поле ниже является первичным ключом
    @GeneratedValue(strategy = GenerationType.AUTO) // Определяет тип генерации значений первичного ключа
    private int id;

    @Column(name="name") // "Связывает" поле ниже с полем name в таблице employee в БД
    private String name;

    @Column (name="age") // "Связывает" поле ниже с полем age в таблице employee в БД
    private int age;

    // getters and setters...
}
É importante notar que faz sentido estudar esse tipo de bean apenas no contexto do estudo da especificação JPA.

Escrevendo um aplicativo: EJB HelloWorld

Nesta seção, escreveremos um pequeno aplicativo Java EE HelloWorld, que implantaremos no servidor GlassFish. Antes de ler este artigo, é altamente recomendável que você leia o artigo sobre como configurar seu ambiente local .
  1. Crie um novo projeto Maven no IntelliJ IDEA.

    Arquivo -> Novo -> Projeto...

    Apresentando EJB-3
  2. Clique em Avançar .

  3. Preencha os parâmetros do projeto Maven:

    Apresentando EJB-4
  4. Clique em Concluir

  5. O projeto foi criado e possui a seguinte estrutura:

    Apresentando EJB-5
O arquivo pom.xml se parece com isto: Apresentando EJB-6Primeiro de tudo, precisamos adicionar uma dependência na API Java EE e também especificar o empacotamento do nosso projeto na forma de um arquivo de aplicação web (war). Para fazer isso, você precisa alterar o código pom.xml para o seguinte formato:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javarush.lectures</groupId>
    <artifactId>ejb_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
    </dependencies>

</project>
A seguir, você pode passar para o código Java. Nossa aplicação será a mais simples. Teremos 1 servlet e 1 EJB. Este será um bean de sessão sem estado. Dentro do EJB definiremos apenas 1 método que retornará a string “Hello World”. Primeiro de tudo, vamos criar um pacote com.javarush.lectures. Então, dentro do pacote com.javarush.lectures, criaremos nosso bean - DemoEJB. O código do bean é fornecido abaixo:
import javax.ejb.Stateless;

@Stateless
public class DemoEJB {
    public String helloWorld() {
        return "Hello world!";
    }
}
Como dito anteriormente, tudo é bastante simples. Nosso próximo passo é criar um servlet que passará o valor do EJB como resposta à solicitação HTTP. Vale a pena notar que servlets não são o tópico deste artigo, mas você ainda precisará usá-los para demonstrar o EJB. Para fazer isso, vamos criar um novo servlet DemoServletno mesmo pacote do EJB. Seu código está abaixo:
@WebServlet("/helloWorld")
public class DemoServlet extends HttpServlet {

    @EJB
    private DemoEJB ejb;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(ejb.helloWorld());
    }
}
Aqui estão alguns breves comentários sobre o código. Abstract @WebServlet("/helloWorld")- define nossa classe como um servlet que processará solicitações HTTP para o endpoint /helloWorld. Nossa classe tem um campo - DemoEJB ejb. Este é o nosso bean definido anteriormente. Uma anotação sobre um campo de classe – @EJBexecuta injeção de dependência (DI). Aqueles. A variável ejb é inicializada automaticamente com uma nova instância quando necessário. Nossa classe é descendente de HttpServlet e substitui um dos métodos da superclasse - doGet. Este método processa solicitações HTTP GET e usa dois parâmetros - HttpServletRequeste HttpServletResponse. HttpServletRequestserve para obter informações sobre uma solicitação HTTP recebida. HttpServletResponsenecessário para gerar uma resposta a uma solicitação. Dentro do método, obtemos o objeto PrintWriterdo objeto de resposta ( HttpServletResponse), usando o método getWriter(). A seguir, podemos escrever algum valor no objeto resultante usando o método write. Que, na verdade, é o que usamos ao escrever no PrintWriterobjeto -a o valor obtido do EJB que definimos (o valor é a string “Hello World!”). O cliente que enviou a solicitação HTTP receberá este valor como resposta à sua solicitação. A próxima etapa é iniciar o aplicativo no servidor GlassFish Java EE. Para isso, criaremos uma nova configuração, conforme descrito no artigo sobre configuração do ambiente local . Abaixo está uma captura de tela da configuração finalizada para o projeto atual. Certifique-se de ter o servidor GlassFish instalado antes de iniciar: Apresentando EJB-7Após criar a configuração de inicialização, inicie o aplicativo usando o menu Executar -> Executar 'ejb_demo' ou usando a tecla de atalho Shift+F10 . Após o lançamento, você poderá ver seus logs: Apresentando EJB-8E também o navegador que se abre: Apresentando EJB-9Tudo isso indica que o aplicativo funciona conforme o esperado.

Conclusão

Neste artigo conhecemos o EJB - Enterprise JavaBeans. Consideramos questões como:
  • O que é EJB?
  • História do EJB
  • Diferentes tipos de EJBs
Lembre-se de que os EJBs vêm nos seguintes tipos:
  • Beans orientados a mensagens (beans orientados a mensagens);
  • Entity Beans - definidos na especificação de entidades JPA (Java Persistence API) e utilizados para armazenar dados;
  • Feijões de sessão:
    • apátrida (sem estado)
    • stateful (com suporte para o estado atual da sessão)
    • singleton (um objeto para toda a aplicação; a partir do EJB 3.1)
Também escrevemos um pequeno aplicativo HelloWorld usando EJB. Como PD, você mesmo pode repetir a parte prática deste artigo. E então adicione mais dois servlets à sua aplicação que usarão beans stateful e singleton para receber o valor.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION