SeamFramework.orgCommunity Documentation

Capítulo 14. Recursos do ambiente de componentes Java EE

14.1. Definindo um recurso
14.2. Injeção typesafe de recursos

Java EE 5 já tinha introduzido um suporte limitado a injeção de dependências, na forma de injeção de componentes do ambiente. Um recurso do ambiente de componentes é um componente Java EE, por exemplo um datasource JDBC, uma fila ou um tópico JMS, um contexto de persistência JPA, um EJB remoto ou um web service.

Naturalmente, agora existe uma leve incompatibilidade com o novo estilo de injeção de dependência em CDI. Mais notadamente, a injeção de componentes no ambiente se baseia em nomes para qualificar tipos ambíguos, e não há real consistência quanto à natureza dos nomes (algumas vezes um nome JNDI, outras vezes um nome de unidade de persistência, às vezes um link EJB, e por vezes um "nome mapeado" não-portável). Os campos produtores acabou se tornando um adaptador elegante para reduzir toda esta complexidade a um modelo comum e obter recursos do ambiente de componentes para participarem do sistema CDI como qualquer outra categoria de bean.

Os campos possuem uma dualidade em que eles podem tanto ser o alvo de uma injeção de componente do ambiente Java EE quanto ser declarado como um campo produtor da CDI. Por esse motivo, eles podem definir um mapeamento a partir de nomes textuais no ambiente de componentes, até uma combinação de tipo e qualificadores usados no mundo da injeção typesafe. Nós chamamos um campo produtor que representa uma referência a um objeto no ambiente de componentes Java EE de recurso.

A especificação CDI utiliza o termo recurso para referir, genericamente, a qualquer das seguintes categorias de objeto que podem estar disponíveis no ambiente de componentes Java EE:

Declaramos um recurso ao anotar um campo produtor com uma anotação de injeção de componentes de ambiente: @Resource, @EJB, @PersistenceContext, @PersistenceUnit ou @WebServiceRef.

@Produces @WebServiceRef(lookup="java:app/service/Catalog")

Catalog catalog;
@Produces @Resource(lookup="java:global/env/jdbc/CustomerDatasource") 

@CustomerDatabase Datasource customerDatabase;
@Produces @PersistenceContext(unitName="CustomerDatabase")

@CustomerDatabase EntityManager customerDatabasePersistenceContext;
@Produces @PersistenceUnit(unitName="CustomerDatabase") 

@CustomerDatabase EntityManagerFactory customerDatabasePersistenceUnit;
@Produces @EJB(ejbLink="../their.jar#PaymentService") 

PaymentService paymentService;

O campo pode ser estático (mas não final).

Uma declaração de recurso contém duas peças de informação:

Este recursos agora podem ser injetados na maneira habitual.

@Inject Catalog catalog;
@Inject @CustomerDatabase Datasource customerDatabase;
@Inject @CustomerDatabase EntityManager customerDatabaseEntityManager;
@Inject @CustomerDatabase EntityManagerFactory customerDatabaseEntityManagerFactory;
@Inject PaymentService paymentService;

O tipo do bean e os qualificadores do recurso são determinados pela declaração do campo produtor.

Pode parecer trabalhoso ter que escrever estas declarações de campos produtores extras, apenas para ganhar um nível adicional de indireção. Você poderia muito bem usar uma injeção de componente do ambiente diretamente, certo? Mas lembre-se que você vai usar recursos como o EntityManager em vários beans diferentes. Não é mais agradável e mais typesafe escrever

@Inject @CustomerDatabase EntityManager

em vez de

@PersistenceContext(unitName="CustomerDatabase") EntityManager

em todos os lugares?