SeamFramework.orgCommunity Documentation

Capítulo 1. Introdução

1.1. O que é um bean?
1.2. Arregaçando as mangas

Então você está interessado em começar a escrever seu primeiro bean? Ou talvez você seja cético, imaginando que tipos de argolas a especificação CDI fará com que você atravesse! A boa notícia é que você provavelmente já escreveu e utilizou centenas, talvez milhares de beans. CDI apenas facilita a realmente utilizá-los para construir uma aplicação!

Um bean é exatamente o que você pensa que é. Só que agora ele tem uma verdadeira identidade no ambiente do contêiner.

Antes do Java EE 6, não havia uma definição clara do termo "bean" na plataforma Java EE. Claro, nós fomos chamando as classes Java usadas em aplicações web e corporativas de "beans" por anos. Houveram até um tanto de diferentes tipos de coisas chamados de "bean" em especificações EE, incluindo os beans do EJB e os managed beans do JSF. Entretanto, outros frameworks de terceiros como Spring e Seam introduziram suas próprias ideias do que significava ser um "bean". O que está faltando é uma definição comum.

Java EE 6, finalmente, estabelece que a definição comum está na especificação de Managed Beans. Managed Beans são definidos como objetos gerenciados pelo contêiner com mínimas restrições de programação, também conhecidos pelo acrônimo POJO (Plain Old Java Object). Eles suportam um pequeno conjunto de serviços básicos, como injeção de recurso, callbacks e interceptadores do ciclo de vida. Especificações complementares, tais como EJB e CDI, se estabelecem sobre este modelo básico. Porém, afinal, existe um conceito uniforme de um bean e um modelo de componente enxuto que está alinhado através da plataforma Java EE.

Com pouquíssimas exceções, quase toda classe Java concreta que possui um construtor com nenhum parâmetro (ou um construtor designado com a anotação @Inject) é um bean. Isso inclui qualquer JavaBean e qualquer EJB session bean. Se você já possui alguns JavaBeans ou session beans, eles já são beans—você não vai precisar de qualquer metadado especial adicional. Há apenas uma pequena coisa que você precisa fazer antes de começar a injetá-los dentro das coisas: você precisa colocá-los em um arquivo (um jar ou um módulo Java EE, como um war ou um jar EJB) que contenha um arquivo indicador especial: META-INF/beans.xml.

Os JavaBeans e EJBs que você tem escrito todo dia, até agora, não foram capazes de tirar proveito dos novos serviços definidos pela especificação CDI. Mas você será capaz de usar cada um deles com CDI—permitindo que o contêiner crie e destrua instâncias de seus beans e associando-os a um contexto designado, injetando-os dentro de outros beans, usando-os em expressões EL, especializando-os com anotações qualificadoras, até adicionando interceptadores e decoradores para eles—sem modificar seu código existente. No máximo, você precisará adicionar algumas anotações.

Agora vamos ver como criar seu primeiro bean que realmente utiliza CDI.

Suponha que temos duas classes Java existentes, que estamos utilizando durante anos em várias aplicações. A primeira classe divide uma string em uma lista de sentenças:

public class SentenceParser {

   public List<String
> parse(String text) { ... }
}

A segunda classe existente é um stateless session bean de fachada (front-end) para um sistema externo que é capaz de traduzir frases de uma língua para outra:

@Stateless

public class SentenceTranslator implements Translator {
   public String translate(String sentence) { ... }
}

Onde Translator é a interface local do EJB:

@Local

public interface Translator {
   public String translate(String sentence);
}

Infelizmente, não temos uma classe pré-existente que traduz todo o texto de documentos. Então vamos escrever um bean que faz este trabalho:

public class TextTranslator {

   private SentenceParser sentenceParser;
   private Translator sentenceTranslator;
    
   @Inject
   TextTranslator(SentenceParser sentenceParser, Translator sentenceTranslator) {
      this.sentenceParser = sentenceParser;
      this.sentenceTranslator = sentenceTranslator;
   }
    
   public String translate(String text) {
      StringBuilder sb = new StringBuilder();
      for (String sentence: sentenceParser.parse(text)) {
          sb.append(sentenceTranslator.translate(sentence));
      }
      return sb.toString();
   }
}

Mas espere! TextTranslator não tem um construtor sem parâmetros! Isto é ainda um bean? Se você lembrar, uma classe que não tem um construtor sem parâmetros ainda pode ser um bean, se tiver um construtor anotado com @Inject.

Como você imaginou, a anotação @Inject tem algo a ver com injeção de dependencia! @Inject pode ser aplicada a um construtor ou a um método de um bean, e diz ao contêiner para chamar este construtor ou este método ao instanciar o bean. O contêiner injetará outros beans nos parâmetros do construtor ou do método.

Vamos criar um bean controlador de UI que utiliza injeção em campo para obter uma instância de TextTranslator, traduzindo o texto digitado por um usuário:

Vamos criar um bean controlador de UI que utiliza injeção em campo para obter uma instância de TextTranslator, traduzindo o texto digitado por um usuário:

Alternativamente, podemos obter e injetar uma instância de TextTranslator programaticamente a partir de uma instância de Instance, parametrizada com o tipo do bean:

@Inject Instance<TextTranslator

> textTranslatorInstance;
...
public void translate() {
   textTranslatorInstance.get().translate(inputText);
}

Repare que não é necessário criar um método getter ou setter para injetar um bean dentro de outro. CDI pode acessar um campo injetado diretamente (mesmo se ele for privado!), que algumas vezes ajuda a eliminar algum código supérfluo. O nome do campo é arbitrário. É o tipo do campo que determina o que é injetado.

Durante a inicialização do sistema, o contêiner deve validar que existe exatamente um bean que satisfaça cada ponto de injeção. Em nosso exemplo, se nenhuma implementação de Translator está disponível—se o EJB SentenceTranslator não foi implantado—o contêiner iria nos informar sobre uma dependência não satisfeita. Se mais de uma implementação de Translator estivessem disponíveis, o contêiner iria nos informar sobre a dependência ambígua.

Antes de aprofundarmos nos detalhes, vamos fazer uma pausa e examinar a anatomia de um bean. Que aspectos do bean são significantes e o que lhe confere sua identidade? Em vez de apenas dar exemplos de beans, vamos definir o que torna algo um bean.