Java CDI: O que é, como se reproduzem e onde vivem os componentes automágicos
Usando Java CDI em projetos Jakarta EE ou Microprofile.io
============

:Author:   Victor Osório
:Email:    victor.perticarrari@gmail.com
:Date:     2019-07-10
:Revision: 1.0.0

Introdução
----------
Java CDI é uma especificação que pode nos ajudar a dar velocidade e padronização ao desenvolvimento. Ela nos permite que possamos criar projetos com baixo acoplamento e alta coesão, algo muito desejado para que criar bons projetos.

O termo automágico foi copiado de uma apresentação de 2015 que está disponível na página da especificação. Ela revela algo muito importante sobre essa especificação, ela nos permite desenvolver sem se preocupar (não usaria o termo importar) com instanciação, dependências e finalização de certos objetos.

Definições
----------
Antes de apresentar o *Java CDI*, é preciso apresentar algumas definições que nos ajudarão a entender melhor do que estamos falando. São elas:

* Jakarta EE (antigo Java EE)
* Container Jakarta EE
* Inversão de Controle
* Programação Orientada a Aspecto

Jakarta EE ou Java EE
~~~~~~~~~~~~~~~~~~~~~
A grosso modo, *Jakarta EE*, ou como era conhecido antigamente *Java EE* é um modelo de programação onde a lógica de negocios é o foco do desenvolvimento. Toda e qualquer feature que não seja referente a lógica de negócios deve ser delegada para o *Container Java EE* como uma configuração.

Uma aplicação Java EE não deverá depender de uma implementação especifica, a compilação dependerá de uma série de APIs e a implementação dessas APIs será carregada em Tempo de Execução pelo *Container Java EE*.

*De fato*, o Mundo do Java EE sempre estará um passo atrás em termos de inovação tecnologica, pois muitas das novas tecnologias ainda não estarão especificadas enquanto já em uso. 

*Porém*, estará um passo a frente pois proporá uma padronização a tecnologia já existente aglutinando boas práticas e provendo uma maior variedade de soluções para um mesmo problema.

Java EE Container
~~~~~~~~~~~~~~~~~
Containers são a implementação concreta de todas as especificações Java EE. Os containers disponíveis no mercado são link:https://wildfly.org/[WildFly], link:https://thorntail.io/[Thorntail], link:https://www.payara.fish/[Payara], link:https://projects.eclipse.org/projects/ee4j.glassfish[GlassFish] e link:https://tomee.apache.org/[Apache TomEE].

Background
----------

IoC - Inversão de Controle 
~~~~~~~~~~~~~~~~~~~~~~~~~~
link:https://martinfowler.com/bliki/InversionOfControl.html[Segundo Martin Fowler], Inversão de Controle é um padrão de programação diferencia um framework de uma biblioteca. Enquanto em uma biblioteca você tem que conectar as coisas para conseguir algo, com a Inversão do Controle você consegue algo e as coisas se conectam.

O Java CDI adiciona um conceito à Inversão de Controle, o Contexto. Então os objetos de uma aplicação além de carregar suas dependências, deverão definir quais contextos possuem. Você verá que isso pode ser feito facilmente!

JSRs
~~~~
O Java CDI foi especificado pelas JSR abaixo:

* *JSR 330*: Dependency Injection for Java
* *JSR 346*: Contexts and Dependency Injection for JavaTM EE 1.1
* *JSR 365*: Contexts and Dependency Injection for JavaTM 2.0

Vale a pena ler! Basta ler a JSR 365, com ela você terá uma visão mais geral, apresentando todos os casos possíveis de uso.

EJB, Managed Beans, Interceptors, etc...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java CDI vem para enriquecer essas especificações e trabalhar simultaneamente, porém um o escopo um pouco diferente.

Managed Beans
-------------

Essa especificação podemos afirmar que é a base do CDI. Toda classe Java é eligivel para ser um Bean, basta ter:

* Um construtor publico sem argumentos

Toda vez que falarmos de Bean, estamos falando de objeto que pode ser injetável em outra classe.

Injeção de Dependências
-----------------------
Proposto pela *JSR 330*, esta tem o objetivo de padronizar:

. Um conjunto de Annotations para uso em classes injetáveis
. Uma API de configuração de injetor fácil de usar e altamente tipada

Para podermos usar a Injeção de Dependências, adicionar a Annotation `@Inject`:

[source,java]
----
@Path(“/user”)
public class UserEndpoint {
    @Inject
    private Repository<User, String> userRepository;
    
    @POST
    public User create(@Valid User newUser) {
        return this.userRepository.create(newUser);
    }
}
----

Qualquer objeto que seja um Bean pode ser adicionado a outro bean. Esse é a funcionalidade básica do Java CDI.

Injetando Contexto
------------------

Agora vamos complicar um pouco. Nosso bean ele deveria ser único apenas em um determinado contexto. Para resolver isso, o Java CDI define uma série de escopos possíveis para um bean:

* Application
* Session
* Conversation
* Request 

Esses contextos eles são definidos juntamente com o Bean. Quem usa o Bean não precisa saber qual é o contexto dele. Abaixo criaremos um bean em que o escopo é a Request, isso significa que o momento da criação será quando a Request for iniciada e será destruido quando a request for finalizada. Sua função será armazenar alguns dados de usuário.

[source,java]
----
@RequestScoped
public class UserCredentials {
 // TODO
}

Inicializando Dependências
--------------------------

Quando o Bean que iremos injetar no código é um pouco mais complexo