Você está na página 1de 23

Guia itexto: Injeo de Dependncias com Spring Framework 3

http://devkico.itexto.com.br

Injeo de Dependncias com
Spring Framework 3
O objetivo deste guia expor o
relacionadas ao container de Injeo de Dependncias (
Spring Framework 3.0. O assunto pode interessar o
! Trata-se do ncleo do Spring Framework: sendo assim conhecimento
obrigatrio para todos aqueles que des
! Ainda mais importante: um padro de projeto que aumenta de forma
significativa a qualidade dos sistemas nos quais aplicado.
interesse pelo Spring Framework, poder
containeres como Pico, miocc ou

Caminhando para a Injeo de Dependncias
Um projeto de software ruim
fragilidade e imobilidade. Frgil
modificao nos deparamos com efeitos inesperados em outros de seus componentes.
rigidez conseqncia desta fragilidade
desenvolvedor v suas opes de atuao limitadas
imobilidade diz respeito dificuldade em se extrair partes do sistema que possam ser
reaproveitadas em outros projetos.
Estes trs problemas possuem
considerado de alto acoplamento qua
dependentes. Por componentes
externos ou internos.
Para melhor entender o problema
um software que busque ttulos de livros escritos por determinado autor.
podemos ver sua estrutura inicial
Na classe cliente temos um nico mtodo chamado
funo buscaPorAutor da classe DAOLivro que
nome do autor passado como parmetro
usa como fonte de dados um arquivo
Por anos este sistema poder funcionar sem problemas
necessrio usar alguma outra fonte de d
Podemos imaginar duas solues que no usem orientao a objetos para resolver o
problema:
! Na classe DAOLivro
buscaPorAutorNoSGBD, que faria a consulta usando um banco de
uma soluo interessante, pois
incluindo uma nova funo que
funo de buscaPorAutor.
! Tambm podemos alterar a funo
no qual pudssemos definir qual a fonte
mesmo problema da soluo anterior.
Imagem 1 - Nosso modelo inicial
pendncias com Spring Framework 3
Injeo de Dependncias com
Spring Framework 3
expor o porqu, como usar e quais as melhores prticas
container de Injeo de Dependncias (Dependency Injection, ou DI
O assunto pode interessar o leitor pelas seguintes razes:
se do ncleo do Spring Framework: sendo assim conhecimento
obrigatrio para todos aqueles que desejem us-lo ou seus derivados.
Ainda mais importante: um padro de projeto que aumenta de forma
significativa a qualidade dos sistemas nos quais aplicado. Mesmo que o leitor no se
interesse pelo Spring Framework, poder us-lo em seus trabalhos adotand
como Pico, miocc ou mesmo o seu prprio se for o caso.
Injeo de Dependncias
Um projeto de software ruim costuma apresentar trs caractersticas
Frgil aquele sistema no qual ao se introduzir uma
modificao nos deparamos com efeitos inesperados em outros de seus componentes.
desta fragilidade: dada a dificuldade em se manter o sistema o
desenvolvedor v suas opes de atuao limitadas (ou mesmo anuladas)
imobilidade diz respeito dificuldade em se extrair partes do sistema que possam ser
reaproveitadas em outros projetos.
problemas possuem a mesma causa: o alto acoplamento. Um sistema
considerado de alto acoplamento quando seus componentes internos so fortemente
dependentes. Por componentes devem ser entendidas classes, fontes de dados,
Para melhor entender o problema vamos usar um exemplo bastante trivial que ser
usque ttulos de livros escritos por determinado autor. Na imagem 1
podemos ver sua estrutura inicial.
Na classe cliente temos um nico mtodo chamado buscar(), que faz uma chamada
da classe DAOLivro que encontra ttulos de livros escritos p
passado como parmetro. Imaginemos por um momento que DAOLivro
usa como fonte de dados um arquivo texto.
Por anos este sistema poder funcionar sem problemas. Mas e se no futuro fosse
outra fonte de dados, digamos, um banco de dados relacional?
Podemos imaginar duas solues que no usem orientao a objetos para resolver o
Na classe DAOLivro poderamos criar um novo mtodo chamado
, que faria a consulta usando um banco de dados relacional. No
uma soluo interessante, pois estaramos aumentando a complexidade da classe
incluindo uma nova funo que, do ponto de vista das classes cliente, exerceria a mesma
alterar a funo buscaPorAutor incluindo um novo parmetro
definir qual a fonte de dados a ser usada. De novo cairamos
mesmo problema da soluo anterior.
Injeo de Dependncias com
as melhores prticas
Dependency Injection, ou DI) do
pelas seguintes razes:
se do ncleo do Spring Framework: sendo assim conhecimento
Ainda mais importante: um padro de projeto que aumenta de forma
que o leitor no se
adotando outros
caractersticas: rigidez,
ao se introduzir uma
modificao nos deparamos com efeitos inesperados em outros de seus componentes. A
: dada a dificuldade em se manter o sistema o
mo anuladas). J a
imobilidade diz respeito dificuldade em se extrair partes do sistema que possam ser
alto acoplamento. Um sistema
ndo seus componentes internos so fortemente
entendidas classes, fontes de dados, sistemas
usar um exemplo bastante trivial que ser
imagem 1
, que faz uma chamada
escritos pelo
DAOLivro
Mas e se no futuro fosse
ados, digamos, um banco de dados relacional?
Podemos imaginar duas solues que no usem orientao a objetos para resolver o
criar um novo mtodo chamado
dados relacional. No
aumentando a complexidade da classe
exerceria a mesma
incluindo um novo parmetro
cairamos no
id4346140 pdfMachine by Broadgun Software - a great PDF writer! - a great PDF creator! - http://www.pdfmachine.com http://www.broadgun.com
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br


Dado que estamos lidando com
orientada a objetos, uma solu
expe um segundo modelo proposto para nosso sistema.


O que : Padres de Projeto

O conceito de padres de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e
posteriormente adaptado para o desenvolvimento de software orientado a objeto
problemas recorrentes na criao de software que possuem solues padronizadas e fornecem um vocabulrio em
comum para todos aqueles que os aplicam. Um exemp

O que : Padro de Projeto Factory

O padro factory fornece uma interface para criao de famlias de objetos correlatos ou dependentes. Uma
possvel implementao do padro a que apresentamos
criar novas instncias de objetos que implementem determinada interface, fazendo com que apenas uma nica
classe do sistema venha a ter dependncias diretas com todas as implementaes presentes de det
ou interface.

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da
classe FactoryDAOLivro, a segunda responsvel por instanciar a implementao correta
de IDAOLivro a partir do nome da fonte de dados
chamar a funo criarIDAOLivro
interessantes:
! A classe Cliente dependente apenas da interface IDAOLivro, e no
implementao especfica. Sendo assim agora possvel trabalhar
dados imaginvel, desde que implemente a interface IDAOLivro.
! A responsabilidade pela instanciao de objetos que implementem a interface
IDAOLivro fica centralizada em uma nica classe, reduzindo significativamente a
complexidade do sistema.


1
O termo se consagrou na disciplina de engenharia de software com o livro Padres de Projeto de Erich
Gamma, Richard Helm, Ralph Johnson e John Vlissides (os quatro autores tambm so conhecidos como a
Gangue dos Quatro (Gang of Four ou GoF em ingls)
Imagem 2 - Aplicando o padro Factory
pendncias com Spring Framework 3
Dado que estamos lidando com a plataforma Java e esta em sua essncia
uma soluo mais interessante adotar o padro factory. A
um segundo modelo proposto para nosso sistema.
: Padres de Projeto
O conceito de padres de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e
rmente adaptado para o desenvolvimento de software orientado a objeto
1
. Trata-se de solues para
problemas recorrentes na criao de software que possuem solues padronizadas e fornecem um vocabulrio em
comum para todos aqueles que os aplicam. Um exemplo de padro de projeto o Factory, descrito neste artigo.
: Padro de Projeto Factory
O padro factory fornece uma interface para criao de famlias de objetos correlatos ou dependentes. Uma
possvel implementao do padro a que apresentamos neste artigo: cria-se uma classe cujo nico objetivo
criar novas instncias de objetos que implementem determinada interface, fazendo com que apenas uma nica
classe do sistema venha a ter dependncias diretas com todas as implementaes presentes de determinada classe
Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da
classe FactoryDAOLivro, a segunda responsvel por instanciar a implementao correta
de IDAOLivro a partir do nome da fonte de dados fornecida pela classe Cliente
criarIDAOLivro. A soluo adotada apresenta vantagens bastante
A classe Cliente dependente apenas da interface IDAOLivro, e no
. Sendo assim agora possvel trabalhar com qualquer fonte de
dados imaginvel, desde que implemente a interface IDAOLivro.
A responsabilidade pela instanciao de objetos que implementem a interface
IDAOLivro fica centralizada em uma nica classe, reduzindo significativamente a

O termo se consagrou na disciplina de engenharia de software com o livro Padres de Projeto de Erich
d Helm, Ralph Johnson e John Vlissides (os quatro autores tambm so conhecidos como a
(Gang of Four ou GoF em ingls)
Aplicando o padro Factory
em sua essncia
adotar o padro factory. A imagem 2
O conceito de padres de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e
de solues para
problemas recorrentes na criao de software que possuem solues padronizadas e fornecem um vocabulrio em
, descrito neste artigo.
O padro factory fornece uma interface para criao de famlias de objetos correlatos ou dependentes. Uma
se uma classe cujo nico objetivo
criar novas instncias de objetos que implementem determinada interface, fazendo com que apenas uma nica
erminada classe
Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da
classe FactoryDAOLivro, a segunda responsvel por instanciar a implementao correta
pela classe Cliente ao
A soluo adotada apresenta vantagens bastante
A classe Cliente dependente apenas da interface IDAOLivro, e no de uma
com qualquer fonte de
A responsabilidade pela instanciao de objetos que implementem a interface
IDAOLivro fica centralizada em uma nica classe, reduzindo significativamente a
O termo se consagrou na disciplina de engenharia de software com o livro Padres de Projeto de Erich
d Helm, Ralph Johnson e John Vlissides (os quatro autores tambm so conhecidos como a
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

O que vimos no segundo modelo na realidade a aplicao do princpio de
inverso de dependncias cunhado por Robert C. Martin em 1996 no seu artigo
Dependency Invertion Principle
! Um mdulo de nvel mais
pertencente a um nvel inferior, mas sim de uma abstrao.
! Abstraes no devem depender de detalhes de implementao, mas sim o
contrrio
Em nosso exemplo a classe
interessa como os ttulos dos livros so obtidos, mas sim que os mesmos sejam retornados
de alguma forma para que possa concluir o seu trabalho. No primeiro modelo, esta
dependia diretamente de uma implementao especfica (o arquivo no formato textual
na segunda, passa a depender apenas de uma abstrao que, no caso, a nossa interface
IDAOLivro.
O segundo postulado tambm foi respeitado no segundo modelo. Observe que as
distintas implementaes de IDAOLivro no influenciam de forma alguma esta i
mas sim o contrrio. No caso, todas as implementaes especficas de IDAOLivro
seguem rigidamente as regras definidas pela interface que, no caso, trata
obrigatoriedade de se implementar a funo
Observe que as trs caracter
segundo modelo. Nosso software no mais frgil, pois caso seja feita qualquer alterao
em uma implementao especfica da interface
classe Cliente. Como conseqncia
rigidez) e, ainda mais interessante: obtivemos mobilidade, pois podemos agora transportar
com maior facilidade elementos do nosso sistema para outros projetos.
Mas este modelo ainda
acoplamento da classe Cliente
classe DAOLivro, no segundo
de apresentar uma terceira verso do sistema, cuja ar

A mudana foi sutil: apenas explicitamos a presena de um
classe Cliente do tipo IDAOLivro
Cliente
3
. Agora podemos dizer que atingimos o menor
esta classe.
Porm, por mais que nos esforcemos, se continuarmos seguindo esta linha de
raciocnio sempre nos depararemos com problemas de acoplamento. Basta observar a
classe FactoryDAOLivro, que possui como dependncia tod
presentes no sistema da interface
evolua chegaremos a um momento no qual a classe

2
Este belssimo artigo encontra
http://www.objectmentor.com/publications/dip.pd
3
Poderamos tambm ter criado um setter para este atributo, porm o efeito seria o mesmo.
Imagem 3 - Terceira verso do nosso modelo
pendncias com Spring Framework 3
O que vimos no segundo modelo na realidade a aplicao do princpio de
cunhado por Robert C. Martin em 1996 no seu artigo
Dependency Invertion Principle
2
. Este princpio nos diz duas coisas:
Um mdulo de nvel mais alto jamais deve depender diretamente de outro
m nvel inferior, mas sim de uma abstrao.
Abstraes no devem depender de detalhes de implementao, mas sim o
Em nosso exemplo a classe Cliente um mdulo de nvel superior: no
interessa como os ttulos dos livros so obtidos, mas sim que os mesmos sejam retornados
de alguma forma para que possa concluir o seu trabalho. No primeiro modelo, esta
dependia diretamente de uma implementao especfica (o arquivo no formato textual
na segunda, passa a depender apenas de uma abstrao que, no caso, a nossa interface
O segundo postulado tambm foi respeitado no segundo modelo. Observe que as
distintas implementaes de IDAOLivro no influenciam de forma alguma esta i
mas sim o contrrio. No caso, todas as implementaes especficas de IDAOLivro
seguem rigidamente as regras definidas pela interface que, no caso, trata
obrigatoriedade de se implementar a funo buscaPorAutor.
Observe que as trs caractersticas presentes em um design ruim no se aplicam no
segundo modelo. Nosso software no mais frgil, pois caso seja feita qualquer alterao
em uma implementao especfica da interface IDAOLivro no afetar diretamente a
conseqncia, o sistema agora mais fcil de ser mantido (no h
rigidez) e, ainda mais interessante: obtivemos mobilidade, pois podemos agora transportar
com maior facilidade elementos do nosso sistema para outros projetos.
Mas este modelo ainda est longe do ideal, porque aumentamos o
Cliente. Enquanto na primeira verso sua nica dependncia era a
, no segundo inclumos outra que a classe FactoryIDAOLivro
de apresentar uma terceira verso do sistema, cuja arquitetura exposta na imagem 3
sutil: apenas explicitamos a presena de um atributo daoLivro
IDAOLivro, cuja instncia definida pelo construtor da classe
. Agora podemos dizer que atingimos o menor grau de acoplamento possvel para
Porm, por mais que nos esforcemos, se continuarmos seguindo esta linha de
raciocnio sempre nos depararemos com problemas de acoplamento. Basta observar a
, que possui como dependncia todas as implementaes
presentes no sistema da interface IDAOLivro. quase certo que conforme este sistema
evolua chegaremos a um momento no qual a classe FactoryDAOLivro se tornar um

Este belssimo artigo encontra-se acessvel gratuitamente no endereo
http://www.objectmentor.com/publications/dip.pdf
tambm ter criado um setter para este atributo, porm o efeito seria o mesmo.
Terceira verso do nosso modelo
O que vimos no segundo modelo na realidade a aplicao do princpio de
cunhado por Robert C. Martin em 1996 no seu artigo The
alto jamais deve depender diretamente de outro
Abstraes no devem depender de detalhes de implementao, mas sim o
um mdulo de nvel superior: no lhe
interessa como os ttulos dos livros so obtidos, mas sim que os mesmos sejam retornados
de alguma forma para que possa concluir o seu trabalho. No primeiro modelo, esta
dependia diretamente de uma implementao especfica (o arquivo no formato textual). J
na segunda, passa a depender apenas de uma abstrao que, no caso, a nossa interface
O segundo postulado tambm foi respeitado no segundo modelo. Observe que as
distintas implementaes de IDAOLivro no influenciam de forma alguma esta interface,
mas sim o contrrio. No caso, todas as implementaes especficas de IDAOLivro
seguem rigidamente as regras definidas pela interface que, no caso, trata-se da
sticas presentes em um design ruim no se aplicam no
segundo modelo. Nosso software no mais frgil, pois caso seja feita qualquer alterao
no afetar diretamente a
, o sistema agora mais fcil de ser mantido (no h
rigidez) e, ainda mais interessante: obtivemos mobilidade, pois podemos agora transportar
porque aumentamos o grau de
. Enquanto na primeira verso sua nica dependncia era a
FactoryIDAOLivro. hora
imagem 3.
daoLivro na
, cuja instncia definida pelo construtor da classe
possvel para
Porm, por mais que nos esforcemos, se continuarmos seguindo esta linha de
raciocnio sempre nos depararemos com problemas de acoplamento. Basta observar a
as as implementaes
. quase certo que conforme este sistema
se tornar um
se acessvel gratuitamente no endereo
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

monstro de difcil manuteno. A cada nova implementao de IDAOLivro precisaremos
alter-la e compil-la novamente.



Alm deste problema, temos outro: necessria uma classe que crie uma instncia
de Cliente. Esta, por sua vez, possui o mesmo problema apresentado no modelo 2: duas
dependncias. Resumindo: chegamos ao limite do que podemos fazer usando apenas o
padro Factory.

Entra a Injeo de Dependncias

A injeo de dependncias (Dependency Injection ou DI em ingls) uma forma de
inverso de controle na qual o aspecto a ser invertido , como o prprio nome j diz, a
resoluo de dependncias. Ao invs do desenvolvedor definir manualmente quais as
instncias a serem criadas e injetadas, como fizemos nos trs modelos anteriormente
descritos, delega-se esta tarefa a um container de inverso de controle (IoC) veja o
quadro Injeo de Dependncias ou Inverso de Controle? -, evitando assim a
necessidade de se implementar o padro factory.
Grosso modo, podemos pensar no container de IoC como um factory ideal, capaz
de instanciar qualquer tipo de classe sem que fiquemos presos a uma famlia especfica de
objetos. Porm, como veremos, no caso do Spring este factory vai alm medida que
tambm controla o ciclo de vida dos objetos por ele gerenciados. Para introduzirmos o
conceito, imagine que este container uma classe mgica que sempre nos retorna um
objeto cujo tipo exatamente aquele que estamos precisando. O truque por trs desta
mgica ser exposto no decorrer deste artigo.

O que uma dependncia?

muito raro encontrarmos um software real e til composto por uma nica classe. Na esmagadora maioria das
vezes topamos com classes que possuem atributos cujo tipo so outras classes. Estes atributos que referenciam outros
tipos de classe so o que costumamos chamar de dependncia.


Injeo de Dependncias ou Inverso de Controle?

Se o ncleo do Spring chamado de Container de Inverso de Controle (IoC de Inversion of Control em ingls),
porque estamos usando o termo injeo de dependncias? Porque como bem observou Martin Fowler em seu artigo
Inversion of Control Containers and the Dependency Injection Pattern
4
, os containeres de inverso de controle
como Spring, Pico e outros aplicam um tipo muito especfico de inverso de controle.

E neste momento uma segunda pergunta surge: o que inverso de controle?
Chama-se de inverso de controle a tcnica de desenvolvimento na qual um
aspecto comportamental do sistema delegado a uma entidade externa.
Um exemplo de inverso de controle o EJB. O desenvolvedor implementa o
seu EJB e em seguida faz o deploy no servidor de aplicaes sem precisar se
preocupar com o modo como seu componente ser iniciado, finalizado e
gerenciado, porque neste caso tudo feito pelo servidor. Ao invs de nos
preocuparmos com estas tarefas as delegamos a uma entidade externa, que
normalmente recebe o nome de container.
A inverso de controle esta no ncleo do conceito de framework. Ao
adotarmos um framework, estamos reutilizando a estrutura de uma aplicao
semi-pronta que finalizamos ao inserir nossos prprios componentes

4
O artigo pode ser online neste endereo: http://www.martinfowler.com/articles/injection.html
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

customizados. No caso de aplicaes web este comportamento fica ntido quando
nos lembramos do processo de preenchimento de formulrios, que
framework ao invs de ser implementado manualmente pelo desenvolvedor.
Aps estes exemplos fica ntido
genrico demais para ser adotado no caso do Spring, aonde o foco a resoluo
das dependncias das classes de nosso projeto.

Voltando ao nosso exemplo inicial, ao aplicarmos o padro de injeo de
dependncias acabaramos com uma arquitetura similar exposta na
que o Container no possui nenhuma dependncia direta com nenhuma das
nosso sistema. Outro fator interessante a ser observado a ausncia da classe
FactoryDAOLivro.

No novo modelo todo o processo de instanciao e preenchimento de dependncias
feito pelo container, que instrudo a faz
nos mais variados formatos, desde arquivos no formato XML at anotaes em cdigo
fonte. A partir destes dados e
computacional o container capaz de instanciar
instruamos a faz-lo.
Uma das grandes vantagens deste modelo que neste estgio o desenvolved
encontra prximo do desacoplamento quase total entre seus componentes. Como
conseqncia, temos sistemas com qualidade muito superior, mais fceis de manter e
distribuir nas mais variadas situaes.
Caso surja a necessidade de uma nova implementao
presentes no sistema, tudo o que o desenvolvedor precisa fazer implement
la como um arquivo. jar (ou .class mesmo), incluir a implementao no classpath do
sistema e em seguida alterar o(s) arquivo(s)
necessidade de recompilar o sistema para se adequar a esta nova situao. Obtm
maneira mobilidade total do sistema, visto que com o ncleo pronto e estabilizado o
processo de recompilao se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo aps aplicar Injeo de Dependncias
pendncias com Spring Framework 3
ados. No caso de aplicaes web este comportamento fica ntido quando
nos lembramos do processo de preenchimento de formulrios, que delegado
framework ao invs de ser implementado manualmente pelo desenvolvedor.
Aps estes exemplos fica ntido, portanto que o termo Inverso de Controle
genrico demais para ser adotado no caso do Spring, aonde o foco a resoluo
das dependncias das classes de nosso projeto.
Voltando ao nosso exemplo inicial, ao aplicarmos o padro de injeo de
com uma arquitetura similar exposta na imagem 4
que o Container no possui nenhuma dependncia direta com nenhuma das c
nosso sistema. Outro fator interessante a ser observado a ausncia da classe
odelo todo o processo de instanciao e preenchimento de dependncias
feito pelo container, que instrudo a faz-lo a partir de configuraes que podem estar
nos mais variados formatos, desde arquivos no formato XML at anotaes em cdigo
e usando o mecanismo de reflexo provido pelo
computacional o container capaz de instanciar e injetar todas as dependncias que ns o
Uma das grandes vantagens deste modelo que neste estgio o desenvolved
encontra prximo do desacoplamento quase total entre seus componentes. Como
, temos sistemas com qualidade muito superior, mais fceis de manter e
distribuir nas mais variadas situaes.
ja a necessidade de uma nova implementao de alguma das abstraes
presentes no sistema, tudo o que o desenvolvedor precisa fazer implement-la,
jar (ou .class mesmo), incluir a implementao no classpath do
sistema e em seguida alterar o(s) arquivo(s) de configurao do container sem a
necessidade de recompilar o sistema para se adequar a esta nova situao. Obtm
maneira mobilidade total do sistema, visto que com o ncleo pronto e estabilizado o
processo de recompilao se torna uma tarefa muito mais rara de ser executada.
Nosso modelo aps aplicar Injeo de Dependncias
ados. No caso de aplicaes web este comportamento fica ntido quando
delegado ao
framework ao invs de ser implementado manualmente pelo desenvolvedor.
Inverso de Controle
genrico demais para ser adotado no caso do Spring, aonde o foco a resoluo
Voltando ao nosso exemplo inicial, ao aplicarmos o padro de injeo de
imagem 4. Observe
classes do
nosso sistema. Outro fator interessante a ser observado a ausncia da classe
odelo todo o processo de instanciao e preenchimento de dependncias
que podem estar
nos mais variados formatos, desde arquivos no formato XML at anotaes em cdigo
o ambiente
e injetar todas as dependncias que ns o
Uma das grandes vantagens deste modelo que neste estgio o desenvolvedor se
encontra prximo do desacoplamento quase total entre seus componentes. Como
, temos sistemas com qualidade muito superior, mais fceis de manter e
de alguma das abstraes
la, distribu-
jar (ou .class mesmo), incluir a implementao no classpath do
o do container sem a
necessidade de recompilar o sistema para se adequar a esta nova situao. Obtm-se desta
maneira mobilidade total do sistema, visto que com o ncleo pronto e estabilizado o

Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Spring Framework entra em cena
O objetivo do Spring Framework simplificar o desenvolvimento de aplicaes
corporativas. Na imagem 5 podemos ver todos os mdulos que compem o framework,
que uma alternativa vivel plataforma Java Enterprise Edition. Este incrvel
framework possibilitou usando apenas POJOs obter os mesmos resultados que at ento
s eram possveis com EJB. E tudo isto graas aplicao do conceito de injeo de
dependncias!
Spring pode fazer inmeras coisas, mas quando nos focamos apenas no seu ncleo,
percebemos que estamos lidando na realidade com um container de injeo de
dependncias e programao orientada a aspectos leve. Para melhor entender a sua
definio, convm estudar suas partes.
Por que leve? Spring no intrusivo. Se sua aplicao baseada no Spring,
possvel que suas classes no venham a ter qualquer dependncia direta com o
framework. Nada mais natural, visto que o problema do alto acoplamento justamente o
que o conceito de injeo de dependncias visa resolver.
Programao orientada a aspectos? O Spring oferece desde sua primeira verso
suporte a programao orientada a aspectos. Esta uma tcnica poderosa que permite ao
desenvolvedor separar a lgica de negcios de servios de infra-estrutura presente em
nossa aplicao. importante mencionar esta caracterstica, visto que se trata do outro
pilar do framework alm do container de injeo de dependncias.
Porm nosso foco o container de injeo de dependncias. Sendo assim, iremos
tratar aqui apenas do mdulo Core Container do Spring. Como ser visto, uma
ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se
usar. E esta a beleza deste container.
Imagem 5 Componentes do Spring Framework. Nosso foco no Core Container
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

O container de injeo de dependncias
Chegou o momento de col
injeo do Spring necessrio baixar a ltima verso do framework em seu site oficial
Para este artigo ser usada a verso
modular. Isto quer dizer qu
acompanham a distribuio.

As dependncias do Container

Iremos usar apenas os arquivos que compem o
distribuio oficial estes so nomeados seguindo o seguinte padro: org.
[nome do mdulo].[nmero da verso].RELEASE.jar. Sendo assim, o arquivo
org.springframework. beans.3.0.2.RELEASE.jar por exemplo na realidade o mdulo
beans.
Precisaremos, portanto
expression. A nica dependncia externa do container a biblioteca Commons Logging,
que pode ser obtida em seu site oficial
logging-[nmero da verso].jar em seu classpath.

Como o container funciona

Para que o container seja til, primeiro
suas configuraes podem vir
a opo mais comum), anotaes em cdigo fonte ou
Uma vez alimentado com estas co
internamente representaes dos objetos a serem gerenciados. Estas representaes
definem quais classes devem ser instanciadas,
configuraes como uma receita
instanciar um bean.
Estas receitas de beans no entanto
instanciar e suas interdependncias: definem tambm o escopo de cada bean. Escopos
especificam qual deve ser o tempo de vida
ser removido do container. De imediato o Spring nos fornece 5 tipos de escopo:
prototype, request, session e global session
visto que os demais so usados no dese
foco do nosso artigo. Na tabela 1


5
http://www.springframework.org
6
http://commons.apache.org/logging/
7
O ncleo do Spring totalmente desacoplado de uma fonte especfica de configuraes. Sendo assim o
desenvolvedor pode criar os seus prprio
Imagem 6 Funcionamento de um container
pendncias com Spring Framework 3
container de injeo de dependncias
Chegou o momento de colocar toda esta teoria em prtica. Para usar o container de
injeo do Spring necessrio baixar a ltima verso do framework em seu site oficial
ser usada a verso 3.0.2. O Spring um framework extremamente
modular. Isto quer dizer que no precisamos usar todos os arquivos JAR que
As dependncias do Container
usar apenas os arquivos que compem o Core Container do Spring.
distribuio oficial estes so nomeados seguindo o seguinte padro: org.springframework.
[nome do mdulo].[nmero da verso].RELEASE.jar. Sendo assim, o arquivo
beans.3.0.2.RELEASE.jar por exemplo na realidade o mdulo
dos mdulos beans, context, context.support, core e
. A nica dependncia externa do container a biblioteca Commons Logging,
que pode ser obtida em seu site oficial
6
. Dever ser adicionado o arquivo commons
[nmero da verso].jar em seu classpath.

er seja til, primeiro precisamos configur-lo. No caso do Spring,
de basicamente trs fontes: arquivos no formato XML (que
a opo mais comum), anotaes em cdigo fonte ou programaticamente
7
.
alimentado com estas configuraes, o container ir armazenar
internamente representaes dos objetos a serem gerenciados. Estas representaes
definem quais classes devem ser instanciadas, suas interdependncias. Pense nas
receita a ser seguida pelo Spring quando for necessrio
Estas receitas de beans no entanto dizem mais do que apenas quais classes
instanciar e suas interdependncias: definem tambm o escopo de cada bean. Escopos
qual deve ser o tempo de vida, ou seja, quando um bean j instanciado dever
. De imediato o Spring nos fornece 5 tipos de escopo:
global session. Destes, apenas trataremos dos dois primeiros,
visto que os demais so usados no desenvolvimento de aplicaes web, o que foge do
tabela 1 possvel conhecer a descrio destes 5 escopos.


http://commons.apache.org/logging/ - Na escrita deste artigo a ltima verso disponvel a 1.1.
O ncleo do Spring totalmente desacoplado de uma fonte especfica de configuraes. Sendo assim o
desenvolvedor pode criar os seus prprios parsers de configurao caso seja de seu interesse.
Funcionamento de um container
ocar toda esta teoria em prtica. Para usar o container de
injeo do Spring necessrio baixar a ltima verso do framework em seu site oficial
5
.
3.0.2. O Spring um framework extremamente
e no precisamos usar todos os arquivos JAR que
do Spring. Na
springframework.
[nome do mdulo].[nmero da verso].RELEASE.jar. Sendo assim, o arquivo
beans.3.0.2.RELEASE.jar por exemplo na realidade o mdulo
beans, context, context.support, core e
. A nica dependncia externa do container a biblioteca Commons Logging,
. Dever ser adicionado o arquivo commons-

. No caso do Spring,
trs fontes: arquivos no formato XML (que
, o container ir armazenar
internamente representaes dos objetos a serem gerenciados. Estas representaes
Pense nas
g quando for necessrio
mais do que apenas quais classes
instanciar e suas interdependncias: definem tambm o escopo de cada bean. Escopos
uando um bean j instanciado dever
. De imediato o Spring nos fornece 5 tipos de escopo: singleton,
Destes, apenas trataremos dos dois primeiros,
nvolvimento de aplicaes web, o que foge do
possvel conhecer a descrio destes 5 escopos.
Na escrita deste artigo a ltima verso disponvel a 1.1.
O ncleo do Spring totalmente desacoplado de uma fonte especfica de configuraes. Sendo assim o
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Tabela 1 Escopos do Spring
Escopo Descrio
singleton Trata-se do escopo default do Spring. O container mantm uma
nica instncia do bean definido.
prototype O Spring sempre retorna uma nova instncia do bean caso o
mesmo seja requerido.
request Usado em aplicaes web, define que a instncia do bean possuir
o mesmo tempo de vida que uma requisio HTTP
session Adotado em aplicaes web, define que a instncia do bean se
encontrar armazenada na sesso do usurio, sendo imediatamente
destrudo junto com esta.
global session Tambm usado em aplicaes web, armazena a instncia do bean
em uma sesso global.

Configurado e pronto para o uso, entra a classe cliente, que simplesmente far
requisies ao container do Spring por um bean especfico.

Instanciando o Container

O Spring oferece dois tipos de container: BeanFactory e ApplicationContext. Nossa
primeira boa prtica portanto diz respeito a qual tipo dever ser selecionado.
BeanFactory na realidade uma interface, presente no pacote
org.springframework.beans.factory que representa o container mais simples fornecido
pelo framework, oferecendo apenas suporte a injeo de dependncias e gerenciamento
de ciclo de vida dos beans.
O framework j vem com algumas implementaes desta interface, sendo a mais
usada org.springframework.beans.factory.xml.XmlBeanFactory, que l as configuraes
do container a partir de um documento XML.
Normalmente opta-se por usar o BeanFactory quando o ambiente computacional
oferece restries mais incisivas como por exemplo um Applet.
J ApplicationContext, que tambm uma interface presente no pacote
org.springframework.context uma extenso de BeanFactory e oferece todos os servios
deste e mais alguns como internacionalizao, extensibilidade e gerenciamento de
eventos. As implementaes mais usadas desta interface so
ClassPathXmlApplicationContext e FileSystemXmlApplicationContext. Ambas
consomem suas configuraes a partir de documentos no formato XML e encontram-se
no pacote org.springframework.context.support. A diferena entre uma e outra apenas
aonde os documentos XML se encontram. Enquanto a primeira o busca no classpath da
aplicao a outra o encontra no sistema de arquivos no qual a aplicao executada.
Na esmagadora maioria das vezes voc acabar usando ApplicationContext, a
no ser que possua excelentes razes para no faz-lo. Sendo assim, no transcorrer
deste artigo usaremos apenas ApplicationContext.
H uma diferena de comportamento entre BeanFactory e ApplicationContext. No
caso do ApplicationContext todos os beans com escopo singleton so automaticamente
carregados por default, ao contrrio de BeanFactory, em que beans pertencentes a este
escopo s so inicializados na primeira vez em que so requeridos. Esta uma das razes
pelas quais se costuma usar BeanFactory.

Oculte seu Container
Uma das principais vantagens do Spring ser leve, sendo assim devemos proteger
esta caracterstica ao mximo possvel. De preferncia, apenas uma classe dever
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

referenciar o container do Spring, ocultando-o do restante do sistema. Na listagem 1
podemos ver como obter este resultado. uma classe muito simples mas que nos diz
muita coisa.

Listagem 1: Ocultando o Container de Injeo de Dependncias
public class Container {

private ApplicationContext contextoSpring;

private ApplicationContext getContextoSpring() {
if (contextoSpring == null) {
contextoSpring = new ClassPathXmlApplicationContext("di/spring.xml");
}
return contextoSpring;
}

public Object getBean(String nome) {
ApplicationContext contexto = getContextoSpring();
if (contexto != null) {
try {
return contexto.getBean(nome);
} catch (NoSuchBeanDefinitionException ex) {
return null;
}
}
return null;
}

public static synchronized Container getInstancia() {return _instancia;}

private static Container _instancia = new Container();

private Container() {}

}

O processo de instanciao do container caro do ponto de vista computacional.
Sendo assim, interessante mantermos uma nica instncia de nosso ApplicationContext,
o que conseguimos a partir da implementao do padro singleton na classe Container.
Assim garantimos que uma nica instncia do container ser usada durante todo o
processo de execuo do nosso sistema.

O que : Padro de Projeto Singleton

O padro de projeto Singleton tem como objetivo garantir que uma nica instncia de uma classe seja
criada, alm de tambm fornecer um nico ponto de acesso a mesma. Seu uso um tanto quanto
controverso, sendo normalmente usado apenas em situaes como a exposta na listagem 1 deste artigo.

Na listagem 1 tambm vemos basicamente tudo o que voc precisa saber a respeito
de como obter um bean gerenciado pelo container. Basta executar a funo getBean, que
recebe como parmetro o nome do bean presente no container. Seu valor de retorno do
tipo Object. Se no container no houver um bean com este nome, ser disparada uma
exceo do tipo org.springframework.beans.factory.NoSuchBeanDefinitionException,
razo pela qual lidamos com esta exceo dentro da funo getBean.
Observe que a classe Container possui apenas um nico mtodo pblico, no caso,
getBean. Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma
dependncia direta com o Spring, garantindo assim a leveza do framework.

Alimentando o Container com XML

Para que o container possa nos retornar um bean, antes ele precisa saber o que e
como instanciar. E neste momento que a configurao entra em cena. Tal como dito
anteriormente, h basicamente trs maneiras de se configurar o Spring: atravs de
documentos no formato XML, usando anotaes ou programaticamente.
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Cada uma destas abordagens apresenta suas vantagens e desvantagens, que veremos
no transcorrer deste artigo, porm dada sua natureza, interessante comear pela
configurao via XML, pois esta expe todos os recursos do Spring que sero expostos
no restante deste artigo. Na listagem 2 podemos ver como nossa aplicao inicial pode
ser configurada usando este formato.

Listagem 2: Configurao do Spring de nossa aplicao Inicial
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="cliente" class="di.Cliente">
<property name="daoLivro" ref="daoLivro"/>
</bean>
<bean id="daoLivro" class="di.DAOLivroTexto" scope="prototype">
<property name="arquivo" value="/livros.txt"/>
</bean>
</beans>

O elemento raiz do documento beans. Cada bean gerenciado pelo container
definido pela tag bean. Na listagem 2 podemos ver nossa aplicao configurada para
trabalhar com um uma implementao de IDAOLivro que usa como fonte de dados um
arquivo textual.
O atributo bean possui apenas um atributo obrigatrio, que o class, que especifica
qual classe dever ser instanciada. O atributo id usado para nomear os beans
gerenciados pelo container. Sendo assim, na listagem 2 definimos dois beans: cliente e
daoLivro.
No bean cliente podemos ver a aplicao da injeo de dependncias. No interior
da tag bean que o representa, h a tag property. Esta tag possui o atributo obrigatrio
name, que identifica qual o nome da propriedade que dever ser atribuda pelo container.
Spring utiliza o padro JavaBeans. Sendo assim a classe Cliente dever possuir um setter
para a propriedade daoLivro, o que de fato possui, tal como pode ser conferido na
listagem 3. Na tag property observa-se um outro atributo: ref. O valor deste atributo o
nome do bean que dever ser injetado que, no caso, o bean daoLivro.
interessante observar que a tag property tambm usada para definir o valor de
propriedades do tipo string ou primitivas de um bean. Observe que na listagem 2
definimos a propriedade arquivo do bean daoLivro com o valor /livros.txt usando o
atributo value. Caso o atributo seja do tipo numrico o Spring se encarregar de fazer a
converso necessria para o usurio.

Listagem 3 A classe Cliente
public class Cliente {


private IDAOLivro daoLivro;

public IDAOLivro getDaoLivro() {
return this.daoLivro;
}

public void setDaoLivro(IDAOLivro dao) {
this.daoLivro = dao;
}

public void buscar(String valor) {
List<String> titulos = getDaoLivro().getLivrosAutor(valor);
for (String titulo : titulos) {
System.out.println(titulo);
}
}

public Cliente() {}

public Cliente(IDAOLivro dao) {
setDaoLivro(dao);
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

}

}

Os tipos de injeo de dependncia

No Spring a injeo de dependncias pode ser feita de duas formas: por setter ou
construtor. Acima acabamos de ver a injeo por setter. Este tipo de injeo executado
em duas etapas. Na primeira o construtor default da classe definida par ao bean
executado, gerando uma nova instncia para, em seguida, serem executados os setters
definidos pelas tags property presentes no interior da tag bean. Sendo assim, quando for
adotar a injeo de dependncias por setter, obrigatria a presena do construtor
default.
J a injeo de dependncias por construtor feita definindo-se qual construtor
dever ser executado ao criarmos uma nova instncia do bean. A listagem 4 expe como
o mesmo efeito que obtivemos usando a injeo por setter pode ser obtido ao adotarmos a
injeo por construtor.

Listagem 4 Injeo de dependncias por construtor
<!Definindo o construtor por tipo !
<bean id="clientePorTipo" class="di.Cliente">
<constructor-arg type="di.IDAOLivro" ref="daoLivro"/>
</bean>
<!Definindo pela ordem do atributo do construtor !
<bean id=clientePorOrdem class=di.Cliente>
<constructor-arg index=0 ref=daoLivro/>
</bean>

Para fazer a injeo por construtor usamos a tag constructor-arg. H duas opes
para se definir quais os valores de cada atributo do construtor. A mais recomendada por
tipo. Neste caso constructor-arg dever receber um atributo chamado type (tal como na
listagem 4) que identifique qual o tipo do argumento. O segundo atributo poder ser tanto
ref, caso estejamos referenciando outro bean quanto value se estivermos nos referindo a
um atributo primitivo ou string.
A segunda opo definir os valores dos atributos do construtor a partir de sua
ordem. Na listagem 4 podemos ver como isto feito no bean clientePorOrdem . No caso,
ao invs de usarmos o atributo type, usamos index, que define qual atributo a partir da sua
ordem (sempre iniciando a partir do zero). Esta opo til para se evitar ambigidade na
escolha do construtor caso haja mais de um parmetro pertencente a um mesmo tipo.

Injeo por setter ou construtor?

Como regra geral, opta-se pela injeo por construtores para as dependncias
obrigatrias e injeo por setter para as dependncias opcionais. Os puristas preferem a
injeo por construtores porque assim temos a garantia de que ao obtermos um bean,
estamos lidando com uma instncia completa, com todas as dependncias obrigatrias
preenchidas.
No entanto, a equipe de desenvolvimento do Spring incentiva a injeo por setter,
pois assim evita-se a criao de construtores com vrios atributos, alguns dos quais
definindo inclusive dependncias opcionais. uma maneira de influenciar os
desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a
manuteno.
Outra vantagem da injeo por setter que ela nos permite reconfigurar a instncia
aps obtida, visto que tudo o que o desenvolvedor precisa fazer passar uma nova
dependncia ao setter em questo. Se a pergunta vou precisar alterar alguma
dependncia de minha instncia aps obtida? for positiva, a injeo por setter dever ser
adotada.
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br


Dando nome aos beans

No precisamos nomear um bean. Caso no o faamos, o prprio Spring ir criar
um nome interno para o bean mapeado e, caso este bean sem nome seja o nico de seu
tipo, isto , o nico bean pertencente a determinada classe, podemos inclusive obt-lo
usando o mtodo sobrescrito getBean(Class classe) do ApplicationContext.
Mas esta obviamente no a melhor alternativa. Afinal de contas, nosso sistema
pode crescer, e outros beans pertencentes mesma classe podem acabar no nosso arquivo
de configurao. E neste caso, ao tentar obter um bean pela sua classe ao invs de pelo
seu nome, obteramos uma exceo do tipo
org.springframework.beans.factory.NoSuchBeanDefinitionException nos informando que
h mais de um bean mapeado para aquele tipo especfico.
Sendo assim fundamental saber como dar nome aos nossos beans. A classe bean
possui dois atributos para que possamos executar esta tarefa. O primeiro deles j vimos
nas listagens 2 e 4. Trata-se do atributo id.
Usamos este atributo quando queremos definir um nome nico para nossos beans.
Ao definirmos este atributo para o bean, garantimos que em nosso container s poder
existir um bean como aquele nome. uma boa prtica us-lo por outra razo: alguns
parseadores de XML oferecem otimizaes para este atributo, o que pode nos
proporcionar ganhos em performance e validao destes documentos, visto que o atributo
id o mesmo definido na especificao do formato XML pelo W3C.
Nossa outra opo o atributo name, que nos permite dar um ou mais nomes para
um bean. tambm usado quando necessrio nomear um bean usando caracteres
especiais, o que no permitido na especificao XML. No caso de um bean possuir mais
de um nome, estes podem ser separados por espao, ponto e vrgula (;) ou vrgulas (,). Na
listagem 5 podemos ver alguns exemplos.

Listagem 5 Um bean com mais de um nome
<bean name=cliente;exemplo class=di.Cliente></bean>
<bean name=cliente exemplo class=di.Cliente></bean>
<bean name=cliente,exemplo class=di.Cliente></bean>

comum oferecer mais de um nome a um determinado bean em projetos maiores,
nos quais possam ocorrer situaes nas quais times diferentes trabalhem em subsistemas
distintos a serem integrados. Porm, na esmagadora maioria das vezes o ideal que cada
bean possua um nico nome a fim de se evitar excessos de nomenclatura que acabem por
gerar confuses dentro da equipe.
uma boa prtica adotar padres de nomenclatura aos beans. Um padro bastante
adotado o de se aplicar prefixos aos nomes dos beans que exponham sua finalidade,
como por exemplo o prefixo dao a todos os beans que implementem o padro de projeto
DAO.

Modularizando a configurao

Uma das principais crticas configurao no formato XML a extenso que estes
documentos possam vir a tomar. Realmente, um tanto trabalhoso dar manuteno em
arquivos gigantescos, porm possvel sanar este problema dividindo a configurao em
arquivos distintos. Nestes casos cada arquivo de configurao pode representar uma
camada lgica do sistema ou um mdulo de sua arquitetura.
H duas maneiras de se modularizar a configurao. A primeira delas atravs da
tag <import>, que pode ser inserida em seus documentos XML tal como exemplificado
na listagem 6.

Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Listagem 6 Usando a tag <import>
<beans>
<import resource=servicos.xml/>
<import resource=dao/daos.xml/>
<bean id=cliente class=di.Cliente/>
</beans>

A tag import possui o atributo obrigatrio resource, que define qual arquivo dever
ser importado para a configurao do Spring. Os caminhos dos arquivos a serem
importados sempre so relativos ao do arquivo que est fazendo a importao. Sendo
assim, se o arquivo da listagem 6 estivesse, dentro do classpath do sistema no diretrio
di/recursos o arquivo importado servicos.xml tambm estaria neste mesmo diretrio e
daos.xml se encontraria no path di/recursos/dao.
O outro modo de obter o mesmo resultado usando um construtor especial
oferecido tanto por ClassPathXmlApplicationContext quanto
FileSystemApplicationContext que recebe como parmetros um array de strings
fornecendo os caminhos para os arquivos de configurao a serem usados. A listagem 7
exemplifica este processo usando a classe ClassPathXmlApplicationContext.

Listagem 7 Modularizando a configurao com o construtor especial
String[] arquivos = {di/recursos/spring.xml,
di/recursos/servisos.xml,
di/recursos/dao/daos.xml};
ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos);

Dentre as duas opes a princpio mais interessante a primeira, visto que no
necessrio recompilar o cdigo fonte caso seja necessrio adicionar algum novo arquivo
de configurao ao container. No entanto, a segunda opo se mostra interessante em
situaes nas quais a escolha dos arquivos de configurao envolvam alguma lgica
interna do seu sistema.

Escopo Singleton vs Prototype

Por padro todo bean gerenciado pelo Spring possui escopo singleton.
fundamental compreender a diferena entre os dois escopos bsicos oferecidos pelo
Spring para evitarmos problemas no futuro.
Tal como exposto na tabela 1, quando um bean se encontra no escopo singleton o
Spring se encarregar de manter uma nica instncia deste bean sobre seu controle. Sendo
assim, toda vez que estivermos chamando o bean cliente definido na listagem 2
estaremos obtendo a mesma instncia da classe di.Cliente. No entanto, importante
observar que estamos lidando aqui com um singleton relativo, visto que nada impede que
criemos fora do container uma instncia diferente desta mesma classe chamando seu
construtor padro, por exemplo.
Um fator que precisa ser levado em conta que o BeanFactory e o
ApplicationContext adotam polticas diferentes com relao a beans com escopo
singleton. Quando o ApplicationContext inicializado, por padro todos os beans com
escopo singleton so instanciados e possuem suas dependncias injetadas, ao passo que
no BeanFactory estes s sero preparados no momento em que forem chamados pela
primeira vez.
J no caso do prototype, sempre que pedirmos ao container um bean que pertena a
este escopo obteremos uma nova instncia. Isto nos trs um certo impacto na
performance, visto que sempre ocorrer o processo de preparao do bean, que
composto por duas etapas: instanciao do mesmo e injeo das dependncias.
Na prtica utiliza-se o padro singleton para beans mais complexos e que no
armazenem estado, como por exemplo a classe SessionFactory do Hibernate.
Uma situao para a qual necessrio ficar atento quando um bean com escopo
singleton possui uma dependncia com escopo prototype. preciso ter conscincia de
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

que a injeo de dependncias em um bean s feita no momento em que o bean
instanciado. Sendo assim, a dependncia com escopo prototype injetada no bean singleton
apenas uma vez.
Se voc quiser no entanto que o seu bean com escopo singleton sempre obtenha
uma nova instncia de sua dependncia com escopo prototype, uma soluo tornar este
bean consciente da existncia do container de injeo de dependncias. Esta no uma
boa prtica pois estamos adicionando peso ao Spring, visto que agora uma classe de
negcios da nossa aplicao passa a possuir uma dependncia direta com o container de
injeo de dependncias.
Mas caso seja de fato necessrio, basta que sua classe implemente a interface
org.springframework.context.ApplicationContextAware tal como a verso alternativa da
classe Cliente que encontra-se exposta na listagem 8.

Listagem 8: um bean com conscincia do container de injeo de dependncias
public class Cliente implements ApplicationContextAware {
// o restante da classe igual
private ApplicationContext applicationContext;

public ApplicationContext getContextoSpring() {
return applicationContext;
}

public void setApplicationContext(ApplicationContext ac) throws BeansException {
this.applicationContext = ac;
}

}

O container do Spring ir injetar nas classes que implementem a interface
ApplicationContextAware uma instncia de si mesmo chamando o mtodo
setApplicationContext, que recebe como parmetro uma instncia e ApplicationContext.
Sendo assim, internamente a classe pode pedir ao container que sempre lhe retorne uma
nova instncia de uma de suas dependncias cujo escopo seja singleton.

Inicializao tardia de beans singleton

Tal como falamos na seo anterior, o ApplicationContext por default prepara todos
os beans com escopo singleton no momento em que carregado. Tal comportamento nem
sempre adequado, visto que h situaes nas quais alguns beans so usados somente em
circunstncias muito especficas. Sendo assim, porque carreg-los se talvez nem sejam
necessrios durante a execuo do sistema?
A soluo para o problema simples. Basta adicionarmos o atributo lazy-init tag
bean com o valor true. Agora o bean s ser processado no momento em que for
requerido pela primeira vez. possvel incluir o atributo lazy-init na tag bean tambm:
assim altera-se o comportamento default de carregamento para todos os beans presentes
naquele arquivo de configurao.
No entanto, nem sempre esta uma boa prtica. Enquanto o sistema estiver em
desenvolvimento, interessante que todos os beans sejam carregados, visto que assim
ser possvel encontrar erros de configurao nesta etapa inicial do processo, facilitando
assim a correo de erros.

Autowiring

O container de injeo de dependncias do Spring pode automaticamente descobrir
quais as dependncias de um bean a partir de um recurso bastante interessante chamado
autowiring. Como vantagem, o desenvolvedor pode reduzir significativamente o nmero
de propriedades e construtores que precisa especificar em seus arquivos de configurao.
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja
auto injetado
8
pelo container. Quando este bean for ser iniciado, o container ir varrer
todos os atributos presentes em sua classe e, para cada um, verificar entre as definies
de beans armazenada em seu interior a existncia de um bean que possa ser injetado
naquele ponto. Encontrados todos os candidatos apropriados, estes so injetados no bean.
Caso haja alguma ambigidade, o container no saber qual bean deve ser injetado e,
neste caso, uma exceo do tipo
org.springframework.beans.factory.NoSuchBeanDefinitionException informando qual
atributo no pode ser injetado.
A melhor maneira de entender este conceito v-lo em prtica. Na listagem 9
podemos ver como configurar o Spring para tirar proveito deste recurso. Podemos ver trs
beans definidos: daoLivro, cliente e autowired. O primeiro ser injetado nos demais.
Enquanto na definio do bean cliente precisamos definir todas as dependncias
manualmente, o mesmo no verdade com o bean autowired. Repare que no foi
necessrio incluir em sua definio nenhum construtor ou propriedade, apenas o atributo
autowire com o valor byType.

Listagem 9 Usando autowiring
<beans>
<bean id="daoLivro" class="di.DAOLivroTexto">
<property name="arquivo" value="/livros.txt"/>
</bean>
<bean id="cliente" class="di.Cliente">
<property name="daoLivro" ref="daoLivro"/>
</bean>
<bean name="autowired" class="di.Cliente" autowire="byType">

</bean>
</beans>

Quando lidamos com este recurso, nosso principal oponente a ambigidade. Se na
listagem 9 houvesse mais um bean do tipo di.DAOLivroTexto nos depararamos com um
erro no momento em que o bean autowired fosse iniciado pelo container, pois este no
saberia qual bean injetar na propriedade daoLivro do bean autowired.
Uma das ferramentas que possumos para evitar estes problemas so os modos
fornecidos pelo Spring para encontrar automaticamente as dependncias a serem
injetadas. Na tabela 2 podemos ver todos estes modos, cujos nomes correspondem ao
valor a ser digitado no atributo autowire de um bean automaticamente injetado.

Tabela 2 - Estratgias de auto injeo de dependncias
Modo Descrio
no Comportamento default. Desabilita a auto injeo de dependncias
para o bean.
byName O container ir buscar por dependncias que possuam o mesmo
nome que a propriedade a ser injetada. Sendo assim, na listagem 9
poderamos ter definido a auto injeo usando esta estratgia que
funcionaria sem problemas. Caso no hajam beans com o mesmo
nome presentes entre as definies do container, a exceo
NoSuchBeanDefinitionException.
byType A busca por dependncias ser por tipo. O container ir buscar por
beans que sejam do mesmo tipo que a dependncia a ser injetada.
Havendo mais de uma possibilidade ser disparada uma exceo do
tipo NoSuchBeanDefinitionException.
constructor anloga estratgia byType. A Diferena que ser feita a
injeo de dependncias a partir dos construtores do bean.

8
O termo em ingls que poderia ser adotado ao invs de auto injetado seria autowired
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

autodetect Seguindo esta estratgia o container ir primeiro buscar executar a
injeo de dependncias por construtor. Se for encontrado um
construtor default no bean, o container passar a adotar a estratgia
byType.

Deve-se usar a auto injeo de dependncias apenas em projetos de pequeno e
mdio porte, visto que trata-se de um processo bem menos preciso que a injeo explcita
atravs da definio de propriedades e construtores. Apesar do Spring se esforar ao
mximo para fazer a escolha correta, podem haver situaes nas quais uma injeo
incorreta seja feita. Sendo assim seu uso normalmente desencorajado em projetos
maiores, a no ser que sejam adotadas regras rgidas na nomenclatura dos beans e sua
tipagem.
Caso queira diminuir ainda mais a quantidade de configurao a ser digitada,
possvel definir o comportamento de auto injeo default do container adicionando o
atributo default-autowire tag beans com um dos valores presentes na tabela 2. Assim
todos os beans nela contidos seguiro a mesma poltica.
Para aumentar a preciso da injeo automtica, podemos tambm excluir
candidatos injeo incluindo o atributo autowire-candidate com o valor false na tag
bean do componente que queremos remover do processo de busca.
Outra possibilidade interessante dar preferncia a uma dependncia especfica
adicionando o atributo primary com valo true tag bean correspondente. Em situaes
nas quais ocorram mais de uma possibilidade de escolha, este ser privilegiado no
processo, ajudando assim a diminuir a possibilidade de ambigidade no processo de auto
injeo de dependncias.
Porm, estas duas alternativas acabam por tornar mais complexo o processo de
criao dos arquivos de configurao. Por esta razo uma boa prtica simplesmente no
usar o autowiring em projetos de grande porte.

Callbacks de Ciclo de Vida

H situaes nas quais no basta apenas injetar as dependncias de um bean e
definir seu escopo. So casos nos quais para que um bean esteja pronto para uso, seja
necessrio algum pr-processamento interno antes que o mesmo seja fornecido ao objeto
que o solicitou ao container. Alm disto, h momentos nos quais necessrio que o
prprio bean libere os recursos que usou durante sua existncia.
Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos
beans: inicializao, que executado logo aps todas as dependncias de um bean terem
sido injetadas e destruio, executado apenas aps o container que gerencia o bean ter
sido destrudo.
O callback de inicializao pode ser adicionado ao bean de duas maneiras. A
primeira delas a implementao da interface
org.springframework.beans.factory.InitializingBean. Esta contm um nico mtodo do
tipo chamado afterPropertiesSet() que dispara uma exceo genrica. Na listagem 10 h
um exemplo de sua implementao. Este procedimento no recomendado pois acopla o
bean ao Spring Framework, violando assim um dos principais objetivos do framework
que justamente sua no intruso nas classes do sistema.

Listagem 10 Implementando callbacks de inicializao e destruio no cdigo fonte
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class ClienteCallbacks implements InitializingBean, DisposableBean {

public void afterPropertiesSet() throws Exception {
System.out.println("Todas as dependncias injetadas");
}

Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

public void destroy() throws Exception {
System.out.println("Container destruido");
}

}

A outra opo incluir na tag bean o atributo init-method. O valor do atributo deve
ser o nome de um mtodo definido no bean que no possua atributos e que pode ou no
disparar alguma exceo. Esta a abordagem adequada, visto que assim garantimos que
nosso bean no esteja diretamente acoplado ao Spring Framework.
J o callback de destruio tambm pode ser adicionado usando basicamente os
mesmos procedimentos que adotamos par ao callback de inicializao. Podemos
implementar a interface DisposableBean, que nos obrigar a implementar o mtodo
destroy(), tal como fizemos na listagem 10 ou, se preferirmos, podemos tambm
adicionar o atributo destroy-method tag bean correspondente. O valor do deste atributo
dever ser um mtodo que no possua parmetros. Como no caso do callback de
inicializao, esta a abordagem favorita por evitar o acoplamento de nossas classes ao
cdigo do Spring Framework.
H um detalhe que precisa ser mencionado: o callback de destruio no
executado jamais em beans cujo escopo seja prototype, pois uma vez criado, este bean
no est mais sobre o poder do container de injeo de dependncias, sendo assim
impossvel que o container venha a executar os mtodos de destruio nestes beans.

Alimentando o Container com Anotaes
Uma alternativa ao XML que apareceu pela primeira vez no Spring 2.0 o uso das
anotaes. Trata-se de um caminho bastante interessante para os que gostam de ver suas
configuraes prximas ao cdigo fonte ou sentem-se incomodados com a necessidade de
se escrever documentos XML.
O problema com as anotaes que elas aumentam o peso do Spring ao acoplar
nossas classes ao Spring Framework. Como veremos, possvel diminuir este
acoplamento ao adotarmos anotaes baseadas em JSRs, porm mesmo assim estaremos
aumentando o acoplamento de nossas classes, o que no ocorreria se estivssemos
adotando configuraes puramente baseadas em XML. Outro problema que a
necessidade de se recompilar cdigo ao adicionarmos novos componentes ao nosso
sistema aumenta significativamente.
Porm as anotaes no excluem completamente o XML. Na realidade, XML e
anotaes convivem perfeitamente bem em um mesmo sistema. Voltando ao nosso
sistema inicial, uma verso alternativa baseada em anotaes precisaria de um arquivo de
configurao tal como o exposto na listagem 11.

Listagem 11 Configurando o container para trabalhar com anotaes
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config/>

<context:component-scan base-package="di.anotados"/>

<bean id="daoLivro" class="di.DAOLivroTexto" scope="prototype" primary="true">
<property name="arquivo" value="/livros.txt"/>
</bean>

</beans>

Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Como pode ser observado na listagem 11, ainda estou mapeando um bean usando
XML. Foi feito propositalmente para expor como as duas abordagens, anotaes e XML
convencional convivem perfeitamente lado a lado. Comparando a listagem 11 com a
listagem 2 observa-se a incluso de um novo namespace: context. fundamental que este
seja declarado para que o Spring possa trabalhar com anotaes.
H tambm duas novas tags: <context:annotation-config/> informa o container que
sero usadas configuraes baseadas em anotaes alm do XML convencional. Outra tag
importante <context:component-scan/>. Esta instrui o container a, no momento em que
for inicializado, varrer todas as classes contidas no pacote di.anotados em busca dos
beans a serem gerenciados pelo container.
O leitor atento tambm observar a ausncia do bean cliente. Nesta verso
alternativa do nosso sistema este bean ser configurado usando apenas anotaes. Sendo
assim, implementamos uma classe chamada ClienteComponente exposta na listagem 12.
Esta classe expe praticamente todas as configuraes que expusemos na seo dedicada
configurao baseada em XML.
Dado que os conceitos bsicos da injeo de dependncias foi dado na seo em
que tratamos da configurao proveniente de documentos em formato XML, nosso foco
agora ser em expor os equivalentes daquela configurao ao adotarmos o modelo de
configuraes baseadas em anotaes.

Listagem 12 A classe ClienteComponente
import di.IDAOLivro;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Scope("prototype")
@Component("clienteAnotado")
public class ClienteComponente {


private IDAOLivro daoLivro;

public IDAOLivro getDaoLivro() {
return this.daoLivro;
}

@Resource(name="daoLivro")
public void setDaoLivro(IDAOLivro dao) {
this.daoLivro = dao;
}

@PostConstruct
public void init() {
System.out.println("Fui construido. E meu dao " + getDaoLivro().getClass());
}

@PreDestroy
public void destroy() {
System.out.println("Meu container foi destruido");
}

}

Identificando beans com @Component

Ao varrer o pacote di.anotados o container ir buscar todas as classes que possuam
a anotao @Component. Esta equivale tag bean que vimos anteriormente. Como boa
prtica, interessante passar como parmetro para esta classe um valor do tipo string que
nomeie nosso bean. Caso no seja feito, o container ir criar um nome interno para o
bean, porm este seria de pouca valia para ns, pois um bean realmente til aquele que
possamos usar, e para us-lo, este precisa ser nomeado.
Pense nesta anotao como a dica que enviamos ao container para que identifique
uma de nossas classes como um bean a ser gerenciado.
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br


Definindo o escopo com @Scope

A anotao @Scope o equivalente ao atributo scope da tag bean. Se omitido, ser
adotado o escopo padro do Spring que, tal como j mencionado, o Singleton. Esta
anotao recebe como parmetro o nome do escopo que iremos adotar. Na listagem 12 s
para variar adotamos o escopo prototype.

Definindo dependncias com @Resource

Anotaes tambm possuem um relativo para a tag property. No caso, estamos
falando da anotao @Resource, que deve ser aplicada sobre atributos ou setters de
nossas classes. Este atributo recebe como parmetro o nome do bean que desejamos seja
injetado em nosso bean.
interessante observar que esta anotao no nativa do Spring, mas sim da JSR-
250, cujo objetivo definir anotaes para conceitos semnticos em comum presentes nas
plataformas Java SE e EE. Sendo assim, ao usarmos esta anotao, estamos na realidade
evitando mais uma ligao direta com classes do Spring, o que uma prtica interessante,
visto que no futuro, caso seja necessrio trocar o container de injeo de dependncias
esta tarefa se tornar menos trabalhosa.
Na listagem 12 estamos instruindo o container a injetar o bean daoLivro no bean
clienteAnotado.

Autowiring com @Autowired ou @Inject

Equivalente ao atributo autowired que vimos na configurao baseada em XML
possumos as anotaes @Autowired e @Inject. @Autowired a anotao provida pelo
Spring. Sendo assim, ao adot-la devemos ter em mente que estamos incluindo uma
dependncia direta ao Spring Framework em nosso cdigo fonte. J a anotao @Inject
faz parte da JSR-330, que especifica o mecanismo de injeo de dependncia padro para
a plataforma Java. Sendo assim, o uso de @Inject prefervel ao de @Autowired, pois
assim estamos criando uma dependncia com um padro Java, e no algo to especfico
quanto o Spring.
Na listagem 13 podemos ver um exemplo da aplicao de @Autowired em mais
uma verso de nosso bean cliente, assim possvel expor mais uma diferena entre
@AutoWired e @Inject. No caso, @Autowired possui um atributo adicional chamado
required, que aceita um valor booleano. Quando definido como true, caso no seja
encontrado o bean a ser injetado, uma exceo ser disparada pelo container de injeo de
dependncias.
Esta opo til quando a aplicao est em desenvolvimento, pois permite aos
desenvolvedores encontrar problemas antes que o sistema entre em produo.

Listagem 13 Usando @Autowired
import di.IDAOLivro;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("clienteAnotadoAutowired")
public class ClienteComponenteAutoWired {

@Autowired(required=true)
private IDAOLivro dao;

public IDAOLivro getDaoLivro() {return dao;}
public void setDaoLivro(IDAOLivro dao) {this.dao = dao;}

}

Callbacks de inicializao e destruio com @PostConstruct e @PreDestroy
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br


Na listagem 12 podemos ver a aplicao das anotaes @PostConstruct e
@PreDestroy, que equivalem aos atributos init-method e destroy-method que vimos na
configurao baseada em XML.
Seu uso no poderia ser mais simples: inclua @PostConstruct no mtodo sem
parmetros que dever ser executado aps ter sido feita a injeo de dependncias em seu
bean para identificar o callback de inicializao e @PreDestroy no mtodo sem
parmetros que dever ser executado no momento em que o container de injeo de
dependncias for ser destrudo.

Quando o XML anula as anotaes

Ao ser inicializado, o container do Spring primeiro carrega as configuraes
provenientes de anotaes para em seguida processar as configuraes em formato XML.
Sendo assim, importante que o leitor saiba que, caso um bean seja configurado
inicialmente usando anotaes, e este mesmo bean esteja especificado no formato XML,
as configuraes no segundo formato anularo a primeira.
Este um erro muito comum em times que tenham optado por trabalhar com os
dois formatos, porm pode ser visto tambm como uma alternativa vivel quando se
deseja anular configuraes em cima das quais no possumos controle, como por
exemplo as que esto presentes em classes j compiladas presentes no classpath de nosso
sistema.

Limitaes das anotaes

Atualmente configuraes baseadas em anotaes no permitem que seja mapeado
mais de um bean para uma mesma classe tal como fizemos na listagem 4. Caso seja
necessrio que isto seja feito, o desenvolvedor possui apenas duas alternativas: ou mapeia
apenas um bean usando anotaes para uma classe e o restante usando XML ou faz todo o
trabalho usando apenas XML.
Dentre as duas alternativas, a segunda uma melhor prtica, visto que assim expe
para o time todas as variantes do bean para todos os membros da equipe de uma forma
mais explcita, evitando assim problemas de comunicao dentro do time.
Outra limitao das anotaes que elas no nos permitem definir o valor de
atributos primitivos ou listas, tal como podemos fazer facilmente no caso do XML.



Configurao baseada em Java (100% livre de XML!)

No Spring 3.0 foi introduzido um novo tipo de contexto de aplicao chamado
AnnotationConfigApplicationContext que, pela primeira vez, possibilita ao desenvolvedor
configurar um container de injeo de dependncias do Spring sem a presena de
qualquer arquivo XML, pois toda configurao feita via cdigo.
Trata-se de uma alternativa bastante poderosa que pode ser usada em situaes nas
quais os beans gerenciados pelo container no possam ser definidos apenas
declarativamente como fizemos usando apenas anotaes ou XML. Agora podemos
incluir lgica neste processo de uma maneira bastante simples.
Visto que todos os conceitos referentes ao processo de gerenciamento de beans j
foi tratado nas sees anteriores deste artigo, iremos ver aqui apenas como mapear os
beans usando este novo recurso de uma maneira rpida comparando-o com as maneiras
anteriores.

Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

Apresentando @Configuration e @Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que
o alimenta, no caso, as anotaes @Configuration e @Bean aplicadas a POJOs. Na
listagem 14 podemos ver a aplicao destas anotaes.

Listagem 14 Aplicando as anotaes @Configuration e @Bean
import di.Cliente;
import di.DAOLivroSGBD;
import di.DAOLivroTexto;
import di.IDAOLivro;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanSource {

@Bean(name="daoLivro")
public IDAOLivro getDAOLivro() {
return new DAOLivroTexto();
}

@Bean(name="cliente")
public Cliente getCliente() {
Cliente saida = new Cliente();
saida.setDaoLivro(getDAOLivro());
return saida;
}

@Bean(name="clienteSGBD")
public Cliente getClienteSGBD() {
Cliente saida = new Cliente();
saida.setDaoLivro(new DAOLivroSGBD());
return saida;
}

@Bean(name="clienteAutowired", autowire=Autowire.BY_TYPE)
public Cliente getClienteAutowired() {
return new Cliente();
}

}

Tabela 3 - Atributos de @Bean
Atributo Descrio
name O nome dado ao bean que ser retornado
autowire Qual poltica de autowiring que ser adotada pelo container.
Valores possveis:
Autowire.BY_TYPE
Autowire.BY_NAME
Autowire.NO > Desabilita o autowiring, e o valor default
initMethod Nome do mtodo que dever ser invocado no bean aps este ter
suas dependncias injetadas
destroyMethod Nome do mtodo que dever ser invocado quando o container que
gerencia o bean for destrudo

A classe presente na listagem 14 o que chamamos de Configuration, ou seja, uma
classe anotada com @Configuration e que possui funes anotadas com a anotao
@Bean que produzem beans que sero gerenciados pelo container de injeo de
dependncias do Spring.
Sendo assim, para criar uma classe de configurao, tudo o que o desenvolvedor
precisa fazer anot-la com @Configuration e em seguida implementar uma ou mais
funes anotadas com @Bean, cujos atributos encontram-se listados na tabela 3.

Autowiring
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br


A primeira impresso que temos quando nos deparamos com este novo recurso
que no precisaremos mais da injeo automtica de dependncias, visto que estamos
manualmente criando nossos beans. Felizmente isto no verdade. Para ativar o
autowiring, basta definir o valor do parmetro autowire com o valor Autowire.BY_NAME
ou Autowire.BY_TYPE tal como exposto na tabela 3.
Observando a listagem 14 vemos que o autowiring aplicado no mtodo
getClienteAutowired() usando a estratgia por tipo.

Definindo o escopo
Novamente aqui o padro do Spring se aplica. Se no for definido explicitamente
qual o escopo do bean, este ser interpretado como pertencente ao escopo singleton. Para
que o bean possua um escopo

Callbacks de Inicializao e Destruio

Tal como na configurao baseada em XML como na configurao baseada em
anotaes, tambm podemos definir os callbacks de inicializao e destruio. A
diferena que os definimos com os atributos initMethod e destroyMethod presentes na
anotao @Bean. Exatamente como nos casos anteriores, eles devem conter o nome de
um mtodo que no possua atributos presentes na classe do bean a ser retornado.

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configurao baseada em Java
AnnotationConfigApplicationContext, que se encontra no pacote
org.springframework.context.annotation. Para us-la, no entanto, necessrio adicionar
duas dependncias externas ao seu projeto. No caso as bibliotecas CGLIB e ASM
9
, que
so usadas para manipular bytecode em tempo de execuo.
H dois modos de se alimentar as configuraes de
AnnotationConfigApplicationContext. O desenvolvedor pode criar uma nova instncia
desta classe passando uma nica classe de configurao ou um array de classes de
configurao ou programaticamente. As duas maneiras podem ser vistas na listagem 15.

Listagem 15 Alimentando AnnotationConfigApplicationContext
AnnotationConfigApplicationContext contexto = null;
// Alimentando com uma nica classe de configurao
contexto = new AnnotationConfigApplicationContext(BeanSource.class);
//Alimentando com um array de classes de configurao
contexto = new AnnotationConfigApplicationContext({BeanSource.class,
DataSources.class});
// Alimentando o context programticamente
contexto = new AnnotationConfigApplicationContext();
contexto.register(BeanSource.class);
//aps adicionar todas as classes ao contexto, execute obrigatriamente o mtodo
refresh()
contexto.refresh();


Concluses

Como pudemos ver, o container de injeo do Spring uma ferramenta bastante
rica, que nos permite resolver de maneira elegante o problema do alto acoplamento em
nossos sistemas. Tal como dito na introduo, importante conhecer o conceito de

9
A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial:
http://cglib.sourceforge.net/ Para este artigo foi usada a verso 2.2. J a biblioteca ASM pode ser obtida
em http://asm.ow2.org/. Usamos neste artigo a verso 3.2.
Guia itexto: Injeo de Dependncias com Spring Framework 3
http://devkico.itexto.com.br

injeo de dependncias mesmo que o Spring jamais seja usado, porque seu
conhecimento torna explicita a principal causa de designs ruins de aplicao.
Porm, caso o Spring venha a ser adotado, importante que a sua no intruso seja
mantida o mximo possvel, pois caso contrrio podemos acabar voltando ao problema do
alto acoplamento. Tal como exposto no artigo, conseguimos manter esta leveza a partir da
adoo de configurao no formato XML ou Java e, no caso das anotaes, adotando ao
mximo possvel apenas anotaes que sejam parte de alguma JSR, ao contrrio das que
fazem parte do core do Spring.
O mais interessante, no entanto, a constatao do poder que o conceito de injeo
de dependncias possui. Percebemos este poder ao constatar que apenas o que foi
exposto neste artigo fornece a base para todos os demais componentes do Spring
Framework e seus derivados, como Grails por exemplo.

Referncias
http://www.springframework.org Site oficial do Spring Framework
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ -
Documentao de referncia do Spring Framework 3.0
http://www.objectmentor.com/publications/dip.pdf - Artigo The Dependency
Injection Principle de Robert C. Martin
http://www.martinfowler.com/articles/injection.html - Artigo Inversion of Control
Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo
Injeo de Dependncias





Henrique Lobo Weissmann (o Kico) (kicolobo@itexto.net) consultor Groovy/Grails,
fundador do Grails Brasil e scio da itexto Desenvolvimento de Projetos
(http://www.itexto.com.br), que atua na criao de projetos adotando software livre e muito
Grails. Alm disto, em seu blog (http://devkico.itexto.com.br) expe sua experincia no
desenvolvimento de software.

Você também pode gostar