A história nos mostra que a pouco tempo atraz, os programadores eram completamente responsáveis pelo gerenciamento do ciclo de vida de todos os objetos decorrentes da implementação. Ou seja, os programadores escreviam o determinado código para criar, relacionar, usar e destruir objetos ao longo da execução da determinada solução. Atualmente este quadro mudou, vemos as tecnologias chamadas de “server side” a cada dia engolindo estas responsabilidades. Eu poderia até me arricar em afirmar que esta responsabilidade já foi retirada das mãos dos programadores e passada a ser implementada pela parte ”infraestrutural” da solução. Para aqueles que ainda não conseguiram visualizar o fato, a questão chave é entender que implementar manualmente este gerenciamento objetos não é uma tarefa trivial, que pode ainda crescer em complexidade devida a natureza e escalabilidade da solução. A tecnologia java vem seguindo esta tendência e amadurecendo juntamente ao longo dos anos e hoje, vemos especificações dos chamados “containers” que tem se tornado a parte infraestrutural de sistema com o propósito de assumir esta responsabilidade.
Resumindo: Gerenciar todos os possíveis objetos em uma solução flexível, escalável e algumas vezes distribuída é uma tarefa muito complexa, que por este mesmo motivo foi abandonado pelos programadores e passado para componentes de softwares externos apelidados de containers.
Injeção de Dependência – DI
Se aprofundarmos na questão, veremos que a evolução natural do gerenciamento de objetos por estes controladores externos chamados de containers nortearam para a criação de um padrão que revolucionou a forma de se contruir programas orientados a objetos. É ai que entra a conhecida Dependecy Injection – DI “Injeção de dependência” ou a antigamente chamada de Inversion of Control – IoC “Inversão de controle”. A DI define um padrão de desenvolvimento de programas de computadores utilizado quando é necessário manter baixo o nível de acoplamento entre diferentes módulos de um sistema. Nesta solução as dependências entre os módulos não são definidas programaticamente, mas sim pela configuração de uma infraestrutura de software container que é responsável por “injetar” em cada componente suas dependências declaradas.
Conceitos Chaves da DI
Os container que já eram responsáveis por cuidar dos objetos, passaram a faze-lo com muito mais classe e flexibilidade com a adoção da DI que foi rapidamente popularizado. Segue abaixo um descritivo básico e prático de conceitos de um container com injeção de dependência:
1. Construção de Objetos – o desenvolvedores deixaram de implementar a contrução dos objetos, passando a delegar configuravelmente isso dentro do container de DI. Isto é bem simples de entender: não existe mais operador new dentro dos programas !!! Isto é feito automaticamente e “debaixo dos panos” pelos container. O programador simplemente configura isso de alguma forma no container.
2. Inicialização de Propriedades – os desenvolvedores deixaram de implementar a definição de valores padrões para as propriedades de um objeto criado, delegando também de forma configuravel nos containers.
3. Gerenciamente de Dependência – os desenvolvedores deixaram de implementar a dependências entre os objetos do sistema, delegando também de forma configurável nos containers.
4. Ciclo de Vida – os desenvolvedores deixaram de implementar o tamanho e a forma de visibilidade dos escopos referentes aos objetos durante a execução, passando a configura-los muito mais facilmente dentro do containers.
5. Configurações declarativa - um container DI deve fornecer uma forma de configuração declaravel, ou seja: o meio de declaração de ser um arquivo externo de facil edição e alteração. O XML tem sido o predominante.
O que eu gostaria de pontuar é que eu redundantementee destaquei as palavras “deixaram de implementar“ com o propósito de gerar no leitor a idéia de que com o uso de container de DI, a codigo fonte final deixa possuir as caracteristicas acima mencionadas.
Containers Java
Atualmente existem vários containers já consagrados na tecnologia java, alguns padrões baseados em especificações e outros proprietários. Em alguns casos é até viável combinar alguns dentes em uma mesma solução para se cheguar em um ambiente desejado. Aqui vai algumas sugestões de estudo: Spring, HiveMind e Guice. Não estarei indicando e nem comentando outros containers, por que o foco de hoje é trazer a conhecimento de todos que dentro do JavaServer Faces existe um completo container de DI que venho percebendo ao longo de minhas consultorias que poucas pessoas o conhecem e o usam de verdade.
JSF Managed Bean Facility Container – JSF
Para aqueles que nunca ouviram falar, a tecnologia JSF vem com um completo container DI embutido chamado de Managed Bean Facility. Com ele é possivel fazer todas as operações básicas de um container. O objetivo deste post é apresentar estas operações, mostrando que na maioria das vezes, os desenvolvedores não precisam gastar horas e horas resolvendo ou costurando outros containers externos em aplicações web usando JavaServer Faces.
1. Construção de Objetos
Uns dos primeiros critérios importantes para um container DI é controlar o ciclo de vida (vida e morte) dos objetos e o JSF Bean Facility oferece uma robusta solução para isso. A implementação é feita pela configuração do qualquer POJO no arquivo arquivo faces-config.xml. Veja o exemplo da definição de uma classe e sua configuração que instrui o JSF Bean Facility a gerenciar os objetos dentro um escopo denomidado “request”:
Acabamos de configurar um objeto para ser criado e destruído a cada pedido HTTP feito para aplicação JSF. As páginas faces podem referenciar este objeto usando a EL – Expression Language #{clienteBean.nome}.
2. Ciclo de Vida
Algo importante para se pontuar é que existem 4 escopos que podem ser utilizados para delimitar o ”tempo de vida” de um objeto. Segue um resumo deles:
- application - criado e armazenado no contexto do servlet. Todos os usuários da aplicação compartilham este objeto. Ele é destruído quando a aplicação for desligado “undeploy”.
- session - criado quando a aplicação precisar usar e é armazenado na sessão servlet de cada usuário. Cada usuário tera seu proprio objeto. Ele é destruído quando a sessão do usuário for destruido, não importa a forma.
- request - criado e armazenado no request servlet do pedido HTTP. Ele é destruído ao termino da resposta HTTP.
- none - criado e não é armazenado em nenhum lugar. Ele é criado e passado para o recurso que necessitar. Este objeto não é destruído pelo JSF Bean Facility, ficando a cargo do recurso que esta usando se responsabilizar por isso isso.
3. Inicialização de Propriedades
JSF Bean Facility possui mecanismos bem simples para ser instruido a inicializar propriedades do objetos que estão sobre o seu controle. Segue o exemplo que acrescenta a configuração das propriedades da classe exemplo.Cliente usada no exemplo anterior:
4. Gerenciamento de Dependências
Cuidar das dependências entres os objetos é um dos requisitos fundamentais de um container, e o JSF Bean Facility tambem não deixa a desejar. Os relacionamentos entre os objetos podem ser declados no faces-config.xml através da EL – Expression Language. A única limitação do JSF Bean Facility que vale ser citada é que ele não faz “dependências cíclicas”. Segue abaixo a continuação do mesmo exemplo da classe exemplo.Cliente que agora é agregador de uma classe de chamada de exemplo.Nota. Ou seja, um objeto de Nota sera criado e injetado em um objeto Cliente. Veja as classes completas e a configuração declarativa:
Arquivo faces-config.xml:
Eu coloquei a declaração dos objetos em sequência lógica para ficar didaticamente mais intuitivo, mas eles podem ser declarado em qualquer ordem que serão resolvidos de qualquer forma. Algo importante de se resaltar é que existe uma simples regra: o escopo do objeto agregador deve ser igual ou maior a do objeto dependende. Para qualquer dúvida, releia o tópico 2 que apresenta todos os escopos existentes no container JSF.
Conclusão
JSF Bean Facility reafirma então a popularização do desenvolvimento baseado em POJOs e a centralização de gerenciamento de objetos baseando em containers. Mesmo ele não oferencendo um leque completo de recursos + serviços como encontrado em outros container conhecidos no mercado, o JSF Bean Facility é suficiente eficaz para controlar objetos que seram utilizados na camada da visão, no qual é o lugar do propria filosofia da especificação JSF. Vale lembrar que outros containers mais completos podem ser integrados com ele, criando assim um ambiente único para suportar outras camadas e serviços para o aplicativo final. Os exemplos apresentados foram elaborados com o objetivo único de apresentar e pontuar os determinados recursos discutivos em questão, estando eles incompletos. Estou a disposição para qualquer eventual dúvida, ajuda ou idéia complementar. Para todas as informações e possibilidades consulte os livros Core JSF ou JSF in Action. Até a próxima
.







