guia itexto: inje Œncias com spring framework 3 … · 2016-01-26 · o objetivo deste guia Ø...

23
Guia itexto: Injeªo de DependŒncias com http://devkico.itexto.com.br Injeªo de Spring Fram O objetivo deste guia Ø relacionadas ao container de I Spring Framework 3.0. O assu Trata-se do nœcleo obrigatrio para todos aqueles Ainda mais importan significativa a qualidade dos interesse pelo Spring Framew containeres como Pico, miocc Caminhando para a Injeªo Um projeto de softwa fragilidade e imobilidade. F modificaªo nos deparamos c rigidez Ø conseqüŒncia desta desenvolvedor vŒ suas opı imobilidade diz respeito dif reaproveitadas em outros proje Estes trŒs problemas po considerado de alto acoplam dependentes. Por componente externos ou internos. Para melhor entender o um software que busque ttulo podemos ver sua estrutura inic Na classe cliente temos funªo buscaPorAutor da cl nome do autor passado como usa como fonte de dados um a Por anos este sistema p necessÆrio usar alguma outra Podemos imaginar duas solu problema: Na classe DAOLiv buscaPorAutorNoSGBD, que Ø uma soluªo interessante, incluindo uma nova funªo qu funªo de buscaPorAutor. TambØm podemos alte no qual pudØssemos definir q mesmo problema da soluªo a Imagem 1 - Nosso modelo inicial m Spring Framework 3 e DependŒncias c mework 3 Ø expor o porquŒ, como usar e quais as melhore Injeªo de DependŒncias (Dependency Injection, unto pode interessar o leitor pelas seguintes razıes: do Spring Framework: sendo assim Ø conh s que desejem usÆ-lo ou seus derivados. nte: Ø um padrªo de projeto que aumenta sistemas nos quais Ø aplicado. Mesmo que o lei work, poderÆ usÆ-lo em seus trabalhos adotan ou mesmo o seu prprio se for o caso. o de DependŒncias are ruim costuma apresentar trŒs caractersticas FrÆgil Ø aquele sistema no qual ao se introd com efeitos inesperados em outros de seus compo fragilidade: dada a dificuldade em se manter o ıes de atuaªo limitadas (ou mesmo anulad ficuldade em se extrair partes do sistema que p etos. ossuem a mesma causa: o alto acoplamento. Um mento quando seus componentes internos sªo f es devem ser entendidas classes, fontes de dados problema vamos usar um exemplo bastante trivia os de livros escritos por determinado autor. Na i cial. um œnico mØtodo chamado buscar(), que faz uma lasse DAOLivro que encontra ttulos de livros esc o parmetro. Imaginemos por um momento que D arquivo texto. poderÆ funcionar sem problemas. Mas e se no fu fonte de dados, digamos, um banco de dados r uıes que nªo usem orientaªo a objetos para r vro poderamos criar um novo mØtodo faria a consulta usando um banco de dados relaci pois estaramos aumentando a complexidade ue, do ponto de vista das classes cliente, exerceria erar a funªo buscaPorAutor incluindo um novo qual a fonte de dados a ser usada. De novo cai anterior. com es prÆticas ou DI) do : hecimento de forma itor nªo se ndo outros s: rigidez, duzir uma onentes. A sistema o das). JÆ a possam ser sistema Ø fortemente s, sistemas al que serÆ imagem 1 a chamada critos pelo DAOLivro uturo fosse relacional? resolver o chamado ional. Nªo da classe a a mesma parmetro iramos no

Upload: buithien

Post on 22-Nov-2018

234 views

Category:

Documents


0 download

TRANSCRIPT

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

Injeccedilatildeo de Dependecircncias com

Spring Framework 3

O objetivo deste guia eacute expor o

relacionadas ao container de Injeccedilatildeo de Dependecircncias (

Spring Framework 30 O assunto pode interessar o Trata-se do nuacutecleo do Spring Framework sendo assim eacute conhecimento

obrigatoacuterio para todos aqueles que des

Ainda mais importante eacute um padratildeo de projeto que aumenta de forma

significativa a qualidade dos sistemas nos quais eacute aplicado

interesse pelo Spring Framework poderaacute

containeres como Pico miocc ou

Caminhando para a Injeccedilatildeo de DependecircnciasUm projeto de software ruim

fragilidade e imobilidade Fraacutegil

modificaccedilatildeo nos deparamos com efeitos inesperados em outros de seus componentes

rigidez eacute consequumlecircncia desta fragilidadedesenvolvedor vecirc suas opccedilotildees de atuaccedilatildeo limitadas

imobilidade diz respeito agrave dificuldade em se extrair partes do sistema que possam ser

reaproveitadas em outros projetosEstes trecircs problemas possuem

considerado de alto acoplamento quadependentes Por componentes externos ou internos

Para melhor entender o problema um software que busque tiacutetulos de livros escritos por determinado autor

podemos ver sua estrutura inicial

Na classe cliente temos um uacutenico meacutetodo chamado

agrave funccedilatildeo buscaPorAutor da classe DAOLivro que nome do autor passado como paracircmetro

usa como fonte de dados um arquivo Por anos este sistema poderaacute funcionar sem problemas

necessaacuterio usar alguma outra fonte de dPodemos imaginar duas soluccedilotildees que natildeo usem orientaccedilatildeo a objetos para resolver o

problema Na classe DAOLivro

buscaPorAutorNoSGBD que faria a consulta usando um banco de eacute uma soluccedilatildeo interessante pois

incluindo uma nova funccedilatildeo que

funccedilatildeo de buscaPorAutor Tambeacutem podemos alterar a funccedilatildeo

no qual pudeacutessemos definir qual a fontemesmo problema da soluccedilatildeo anterior

Imagem 1 - Nosso modelo inicial

pendecircncias com Spring Framework 3

Injeccedilatildeo de Dependecircncias com

Spring Framework 3

eacute expor o porquecirc como usar e quais as melhores praacuteticas

container de Injeccedilatildeo de Dependecircncias (Dependency Injection ou DI

O assunto pode interessar o leitor pelas seguintes razotildees

se do nuacutecleo do Spring Framework sendo assim eacute conhecimento

obrigatoacuterio para todos aqueles que desejem usaacute-lo ou seus derivados Ainda mais importante eacute um padratildeo de projeto que aumenta de forma

significativa a qualidade dos sistemas nos quais eacute aplicado Mesmo que o leitor natildeo se

interesse pelo Spring Framework poderaacute usaacute-lo em seus trabalhos adotandcomo Pico miocc ou mesmo o seu proacuteprio se for o caso

Injeccedilatildeo de Dependecircncias Um projeto de software ruim costuma apresentar trecircs caracteriacutesticas

Fraacutegil eacute aquele sistema no qual ao se introduzir uma modificaccedilatildeo nos deparamos com efeitos inesperados em outros de seus componentes

desta fragilidade dada a dificuldade em se manter o sistema o desenvolvedor vecirc suas opccedilotildees de atuaccedilatildeo limitadas (ou mesmo anuladas)imobilidade diz respeito agrave dificuldade em se extrair partes do sistema que possam ser

reaproveitadas em outros projetos problemas possuem a mesma causa o alto acoplamento Um sistema eacute

considerado de alto acoplamento quando seus componentes internos satildeo fortemente

dependentes Por componentes devem ser entendidas classes fontes de dados

Para melhor entender o problema vamos usar um exemplo bastante trivial que seraacute

usque tiacutetulos de livros escritos por determinado autor Na imagem 1

podemos ver sua estrutura inicial

Na classe cliente temos um uacutenico meacutetodo chamado buscar() que faz uma chamada da classe DAOLivro que encontra tiacutetulos de livros escritos p

passado como paracircmetro Imaginemos por um momento que DAOLivro usa como fonte de dados um arquivo texto

Por anos este sistema poderaacute funcionar sem problemas Mas e se no futuro fosse outra fonte de dados digamos um banco de dados relacional

Podemos imaginar duas soluccedilotildees que natildeo usem orientaccedilatildeo a objetos para resolver o

Na classe DAOLivro poderiacuteamos criar um novo meacutetodo chamado

que faria a consulta usando um banco de dados relacional Natildeo

eacute uma soluccedilatildeo interessante pois estariacuteamos aumentando a complexidade da classe incluindo uma nova funccedilatildeo que do ponto de vista das classes cliente exerceria a mesma

alterar a funccedilatildeo buscaPorAutor incluindo um novo paracircmetro

definir qual a fonte de dados a ser usada De novo cairiacuteamos

mesmo problema da soluccedilatildeo anterior

Injeccedilatildeo de Dependecircncias com

as melhores praacuteticas

Dependency Injection ou DI) do pelas seguintes razotildees

se do nuacutecleo do Spring Framework sendo assim eacute conhecimento

Ainda mais importante eacute um padratildeo de projeto que aumenta de forma

que o leitor natildeo se

adotando outros

caracteriacutesticas rigidez ao se introduzir uma

modificaccedilatildeo nos deparamos com efeitos inesperados em outros de seus componentes A dada a dificuldade em se manter o sistema o

mo anuladas) Jaacute a

imobilidade diz respeito agrave dificuldade em se extrair partes do sistema que possam ser

alto acoplamento Um sistema eacute

ndo seus componentes internos satildeo fortemente

entendidas classes fontes de dados sistemas

usar um exemplo bastante trivial que seraacute

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 soluccedilotildees que natildeo usem orientaccedilatildeo a objetos para resolver o

criar um novo meacutetodo chamado

dados relacional Natildeo

aumentando a complexidade da classe exerceria a mesma

incluindo um novo paracircmetro

cairiacuteamos no

id4346140 pdfMachine by Broadgun Software - a great PDF writer - a great PDF creator - httpwwwpdfmachinecom httpwwwbroadguncom

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

Dado que estamos lidando com

orientada a objetos uma soluccedilatilde

expotildee um segundo modelo proposto para nosso sistema

O que eacute Padrotildees de Projeto

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

posteriormente adaptado para o desenvolvimento de software orientado a objetoproblemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

comum para todos aqueles que os aplicam Um exemp

O que eacute Padratildeo de Projeto Factory

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

possiacutevel implementaccedilatildeo do padratildeo eacute a que apresentamos

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

classe do sistema venha a ter dependecircncias diretas com todas as implementaccedilotildees presentes de det

ou interface

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da

classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

de IDAOLivro a partir do nome da fonte de dados chamar a funccedilatildeo criarIDAOLivro

interessantes A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo

implementaccedilatildeo especiacutefica Sendo assim agora eacute possiacutevel trabalhar

dados imaginaacutevel desde que implemente a interface IDAOLivro

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

complexidade do sistema

1 O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

Gamma Richard Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

Gangue dos Quatro (Gang of Four ou GoF em inglecircs)

Imagem 2 - Aplicando o padratildeo Factory

pendecircncias com Spring Framework 3

Dado que estamos lidando com a plataforma Java e esta eacute em sua essecircncia

uma soluccedilatildeo mais interessante eacute adotar o padratildeo factory A

um segundo modelo proposto para nosso sistema

Padrotildees de Projeto

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

rmente adaptado para o desenvolvimento de software orientado a objeto1 Trata-se de soluccedilotildees para

problemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

comum para todos aqueles que os aplicam Um exemplo de padratildeo de projeto eacute o Factory descrito neste artigo

Padratildeo de Projeto Factory

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

possiacutevel implementaccedilatildeo do padratildeo eacute a que apresentamos neste artigo cria-se uma classe cujo uacutenico objetivo eacute

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

classe do sistema venha a ter dependecircncias diretas com todas as implementaccedilotildees presentes de determinada classe

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

de IDAOLivro a partir do nome da fonte de dados fornecida pela classe ClientecriarIDAOLivro A soluccedilatildeo adotada apresenta vantagens bastante

A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo

Sendo assim agora eacute possiacutevel trabalhar com qualquer fonte de dados imaginaacutevel desde que implemente a interface IDAOLivro

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

d Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

(Gang of Four ou GoF em inglecircs)

Aplicando o padratildeo Factory

em sua essecircncia adotar o padratildeo factory A imagem 2

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

de soluccedilotildees para

problemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

descrito neste artigo

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

se uma classe cujo uacutenico objetivo eacute

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

erminada classe

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

pela classe Cliente ao A soluccedilatildeo adotada apresenta vantagens bastante

A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo de uma com qualquer fonte de

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

d Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

inversatildeo de dependecircncias cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle

Um moacutedulo de niacutevel mais

pertencente a um niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

contraacuterio Em nosso exemplo a classe

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

IDAOLivro O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo

Observe que as trecircs caracteriacute

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface

classe Cliente Como consequumlecircncia

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 versatildeo do sistema cuja ar

A mudanccedila foi sutil apenas explicitamos a presenccedila de um

classe Cliente do tipo IDAOLivro

Cliente3 Agora podemos dizer que atingimos o menor esta classe

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

classe FactoryDAOLivro que possui como dependecircncia tod

presentes no sistema da interface evolua chegaremos a um momento no qual a classe

2 Este beliacutessimo artigo encontra

httpwwwobjectmentorcompublicationsdippd3 Poderiacuteamos tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Imagem 3 - Terceira versatildeo do nosso modelo

pendecircncias com Spring Framework 3

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle2 Este princiacutepio nos diz duas coisas

Um moacutedulo de niacutevel mais alto jamais deve depender diretamente de outro m niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

Em nosso exemplo a classe Cliente eacute um moacutedulo de niacutevel superior natildeo

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo buscaPorAutor

Observe que as trecircs caracteriacutesticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface IDAOLivro natildeo afetaraacute diretamente a

consequumlecircncia o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

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 estaacute longe do ideal porque aumentamos o Cliente Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

no segundo incluiacutemos outra que eacute a classe FactoryIDAOLivro

de apresentar uma terceira versatildeo do sistema cuja arquitetura eacute exposta na imagem 3

sutil apenas explicitamos a presenccedila de um atributo daoLivro

IDAOLivro cuja instacircncia eacute definida pelo construtor da classe

Agora podemos dizer que atingimos o menor grau de acoplamento possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

que possui como dependecircncia todas as implementaccedilotildees

presentes no sistema da interface IDAOLivro Eacute quase certo que conforme este sistema

evolua chegaremos a um momento no qual a classe FactoryDAOLivro se tornaraacute um

Este beliacutessimo artigo encontra-se acessiacutevel gratuitamente no endereccedilo

httpwwwobjectmentorcompublicationsdippdf tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Terceira versatildeo do nosso modelo

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo The

alto jamais deve depender diretamente de outro

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

eacute um moacutedulo de niacutevel superior natildeo lhe interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual) Jaacute

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta interface mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trata-se da

sticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

natildeo afetaraacute diretamente a

o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

rigidez) e ainda mais interessante obtivemos mobilidade pois podemos agora transportar

porque aumentamos o grau de Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

FactoryIDAOLivro Eacute hora

imagem 3

daoLivro na cuja instacircncia eacute definida pelo construtor da classe

possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

as as implementaccedilotildees

Eacute quase certo que conforme este sistema

se tornaraacute um

se acessiacutevel gratuitamente no endereccedilo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

monstro de difiacutecil manutenccedilatildeo A cada nova implementaccedilatildeo de IDAOLivro precisaremos alteraacute-la e compilaacute-la novamente

Aleacutem deste problema temos outro eacute necessaacuteria uma classe que crie uma instacircncia

de Cliente Esta por sua vez possui o mesmo problema apresentado no modelo 2 duas dependecircncias Resumindo chegamos ao limite do que podemos fazer usando apenas o padratildeo Factory

Entra a Injeccedilatildeo de Dependecircncias

A injeccedilatildeo de dependecircncias (Dependency Injection ou DI em inglecircs) eacute uma forma de

inversatildeo de controle na qual o aspecto a ser invertido eacute como o proacuteprio nome jaacute diz a resoluccedilatildeo de dependecircncias Ao inveacutes do desenvolvedor definir manualmente quais as

instacircncias a serem criadas e injetadas como fizemos nos trecircs modelos anteriormente descritos delega-se esta tarefa a um container de inversatildeo de controle (IoC) veja o quadro Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle - evitando assim a necessidade de se implementar o padratildeo 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 famiacutelia especiacutefica de

objetos Poreacutem como veremos no caso do Spring este factory vai aleacutem agrave medida que tambeacutem controla o ciclo de vida dos objetos por ele gerenciados Para introduzirmos o conceito imagine que este container eacute uma classe maacutegica que sempre nos retorna um

objeto cujo tipo eacute exatamente aquele que estamos precisando O truque por traacutes desta

maacutegica seraacute exposto no decorrer deste artigo O que eacute uma dependecircncia

Eacute muito raro encontrarmos um software real e uacutetil composto por uma uacutenica classe Na esmagadora maioria das

vezes topamos com classes que possuem atributos cujo tipo satildeo outras classes Estes atributos que referenciam outros

tipos de classe satildeo o que costumamos chamar de dependecircncia

Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle

Se o nuacutecleo do Spring eacute chamado de Container de Inversatildeo de Controle (IoC de Inversion of Control em inglecircs)

porque estamos usando o termo injeccedilatildeo de dependecircncias Porque como bem observou Martin Fowler em seu artigo Inversion of Control Containers and the Dependency Injection Pattern 4 os containeres de inversatildeo de controle

como Spring Pico e outros aplicam um tipo muito especiacutefico de inversatildeo de controle

E neste momento uma segunda pergunta surge o que eacute inversatildeo de controle

Chama-se de inversatildeo de controle a teacutecnica de desenvolvimento na qual um

aspecto comportamental do sistema eacute delegado a uma entidade externa Um exemplo de inversatildeo de controle eacute o EJB O desenvolvedor implementa o

seu EJB e em seguida faz o deploy no servidor de aplicaccedilotildees sem precisar se preocupar com o modo como seu componente seraacute iniciado finalizado e

gerenciado porque neste caso eacute tudo feito pelo servidor Ao inveacutes de nos

preocuparmos com estas tarefas as delegamos a uma entidade externa que normalmente recebe o nome de container

A inversatildeo de controle esta no nuacutecleo do conceito de framework Ao

adotarmos um framework estamos reutilizando a estrutura de uma aplicaccedilatildeo

semi-pronta que finalizamos ao inserir nossos proacuteprios componentes

4 O artigo pode ser online neste endereccedilo httpwwwmartinfowlercomarticlesinjectionhtml

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

customizados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

dependecircncias acabariacuteamos com uma arquitetura similar agrave exposta na

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

FactoryDAOLivro

No novo modelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc

nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

fonte A partir destes dados ecomputacional o container eacute capaz de instanciar

instruamos a fazecirc-lo Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

consequumlecircncia temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees

Caso surja a necessidade de uma nova implementaccedilatildeo

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute

la como um arquivo jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s)necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

pendecircncias com Spring Framework 3

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute delegado

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido portanto que o termo Inversatildeo de Controle

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

com uma arquitetura similar agrave exposta na imagem 4

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das cnosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc-lo a partir de configuraccedilotildees que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

e usando o mecanismo de reflexatildeo provido pelocomputacional o container eacute capaz de instanciar e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees ja a necessidade de uma nova implementaccedilatildeo de alguma das abstraccedilotildees

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute-la jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s) de configuraccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara de ser executada

Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

delegado ao framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Inversatildeo de Controle eacute

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

imagem 4 Observe classes do

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

o ambiente e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolvedor se encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

de alguma das abstraccedilotildees

la distribuiacute-jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

ccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem-se desta maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

Dado que estamos lidando com

orientada a objetos uma soluccedilatilde

expotildee um segundo modelo proposto para nosso sistema

O que eacute Padrotildees de Projeto

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

posteriormente adaptado para o desenvolvimento de software orientado a objetoproblemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

comum para todos aqueles que os aplicam Um exemp

O que eacute Padratildeo de Projeto Factory

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

possiacutevel implementaccedilatildeo do padratildeo eacute a que apresentamos

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

classe do sistema venha a ter dependecircncias diretas com todas as implementaccedilotildees presentes de det

ou interface

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da

classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

de IDAOLivro a partir do nome da fonte de dados chamar a funccedilatildeo criarIDAOLivro

interessantes A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo

implementaccedilatildeo especiacutefica Sendo assim agora eacute possiacutevel trabalhar

dados imaginaacutevel desde que implemente a interface IDAOLivro

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

complexidade do sistema

1 O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

Gamma Richard Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

Gangue dos Quatro (Gang of Four ou GoF em inglecircs)

Imagem 2 - Aplicando o padratildeo Factory

pendecircncias com Spring Framework 3

Dado que estamos lidando com a plataforma Java e esta eacute em sua essecircncia

uma soluccedilatildeo mais interessante eacute adotar o padratildeo factory A

um segundo modelo proposto para nosso sistema

Padrotildees de Projeto

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

rmente adaptado para o desenvolvimento de software orientado a objeto1 Trata-se de soluccedilotildees para

problemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

comum para todos aqueles que os aplicam Um exemplo de padratildeo de projeto eacute o Factory descrito neste artigo

Padratildeo de Projeto Factory

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

possiacutevel implementaccedilatildeo do padratildeo eacute a que apresentamos neste artigo cria-se uma classe cujo uacutenico objetivo eacute

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

classe do sistema venha a ter dependecircncias diretas com todas as implementaccedilotildees presentes de determinada classe

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

de IDAOLivro a partir do nome da fonte de dados fornecida pela classe ClientecriarIDAOLivro A soluccedilatildeo adotada apresenta vantagens bastante

A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo

Sendo assim agora eacute possiacutevel trabalhar com qualquer fonte de dados imaginaacutevel desde que implemente a interface IDAOLivro

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

d Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

(Gang of Four ou GoF em inglecircs)

Aplicando o padratildeo Factory

em sua essecircncia adotar o padratildeo factory A imagem 2

O conceito de padrotildees de projeto foi cunhado por Cristopher Alexander no contexto da arquitetura civil e

de soluccedilotildees para

problemas recorrentes na criaccedilatildeo de software que possuem soluccedilotildees padronizadas e fornecem um vocabulaacuterio em

descrito neste artigo

O padratildeo factory fornece uma interface para criaccedilatildeo de famiacutelias de objetos correlatos ou dependentes Uma

se uma classe cujo uacutenico objetivo eacute

criar novas instacircncias de objetos que implementem determinada interface fazendo com que apenas uma uacutenica

erminada classe

Nesta nova arquitetura a classe Cliente depende agora da interface IDAOLivro e da classe FactoryDAOLivro a segunda responsaacutevel por instanciar a implementaccedilatildeo correta

pela classe Cliente ao A soluccedilatildeo adotada apresenta vantagens bastante

A classe Cliente eacute dependente apenas da interface IDAOLivro e natildeo de uma com qualquer fonte de

A responsabilidade pela instanciaccedilatildeo de objetos que implementem a interface

IDAOLivro fica centralizada em uma uacutenica classe reduzindo significativamente a

O termo se consagrou na disciplina de engenharia de software com o livro Padrotildees de Projeto de Erich

d Helm Ralph Johnson e John Vlissides (os quatro autores tambeacutem satildeo conhecidos como a

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

inversatildeo de dependecircncias cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle

Um moacutedulo de niacutevel mais

pertencente a um niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

contraacuterio Em nosso exemplo a classe

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

IDAOLivro O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo

Observe que as trecircs caracteriacute

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface

classe Cliente Como consequumlecircncia

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 versatildeo do sistema cuja ar

A mudanccedila foi sutil apenas explicitamos a presenccedila de um

classe Cliente do tipo IDAOLivro

Cliente3 Agora podemos dizer que atingimos o menor esta classe

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

classe FactoryDAOLivro que possui como dependecircncia tod

presentes no sistema da interface evolua chegaremos a um momento no qual a classe

2 Este beliacutessimo artigo encontra

httpwwwobjectmentorcompublicationsdippd3 Poderiacuteamos tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Imagem 3 - Terceira versatildeo do nosso modelo

pendecircncias com Spring Framework 3

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle2 Este princiacutepio nos diz duas coisas

Um moacutedulo de niacutevel mais alto jamais deve depender diretamente de outro m niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

Em nosso exemplo a classe Cliente eacute um moacutedulo de niacutevel superior natildeo

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo buscaPorAutor

Observe que as trecircs caracteriacutesticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface IDAOLivro natildeo afetaraacute diretamente a

consequumlecircncia o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

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 estaacute longe do ideal porque aumentamos o Cliente Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

no segundo incluiacutemos outra que eacute a classe FactoryIDAOLivro

de apresentar uma terceira versatildeo do sistema cuja arquitetura eacute exposta na imagem 3

sutil apenas explicitamos a presenccedila de um atributo daoLivro

IDAOLivro cuja instacircncia eacute definida pelo construtor da classe

Agora podemos dizer que atingimos o menor grau de acoplamento possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

que possui como dependecircncia todas as implementaccedilotildees

presentes no sistema da interface IDAOLivro Eacute quase certo que conforme este sistema

evolua chegaremos a um momento no qual a classe FactoryDAOLivro se tornaraacute um

Este beliacutessimo artigo encontra-se acessiacutevel gratuitamente no endereccedilo

httpwwwobjectmentorcompublicationsdippdf tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Terceira versatildeo do nosso modelo

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo The

alto jamais deve depender diretamente de outro

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

eacute um moacutedulo de niacutevel superior natildeo lhe interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual) Jaacute

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta interface mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trata-se da

sticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

natildeo afetaraacute diretamente a

o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

rigidez) e ainda mais interessante obtivemos mobilidade pois podemos agora transportar

porque aumentamos o grau de Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

FactoryIDAOLivro Eacute hora

imagem 3

daoLivro na cuja instacircncia eacute definida pelo construtor da classe

possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

as as implementaccedilotildees

Eacute quase certo que conforme este sistema

se tornaraacute um

se acessiacutevel gratuitamente no endereccedilo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

monstro de difiacutecil manutenccedilatildeo A cada nova implementaccedilatildeo de IDAOLivro precisaremos alteraacute-la e compilaacute-la novamente

Aleacutem deste problema temos outro eacute necessaacuteria uma classe que crie uma instacircncia

de Cliente Esta por sua vez possui o mesmo problema apresentado no modelo 2 duas dependecircncias Resumindo chegamos ao limite do que podemos fazer usando apenas o padratildeo Factory

Entra a Injeccedilatildeo de Dependecircncias

A injeccedilatildeo de dependecircncias (Dependency Injection ou DI em inglecircs) eacute uma forma de

inversatildeo de controle na qual o aspecto a ser invertido eacute como o proacuteprio nome jaacute diz a resoluccedilatildeo de dependecircncias Ao inveacutes do desenvolvedor definir manualmente quais as

instacircncias a serem criadas e injetadas como fizemos nos trecircs modelos anteriormente descritos delega-se esta tarefa a um container de inversatildeo de controle (IoC) veja o quadro Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle - evitando assim a necessidade de se implementar o padratildeo 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 famiacutelia especiacutefica de

objetos Poreacutem como veremos no caso do Spring este factory vai aleacutem agrave medida que tambeacutem controla o ciclo de vida dos objetos por ele gerenciados Para introduzirmos o conceito imagine que este container eacute uma classe maacutegica que sempre nos retorna um

objeto cujo tipo eacute exatamente aquele que estamos precisando O truque por traacutes desta

maacutegica seraacute exposto no decorrer deste artigo O que eacute uma dependecircncia

Eacute muito raro encontrarmos um software real e uacutetil composto por uma uacutenica classe Na esmagadora maioria das

vezes topamos com classes que possuem atributos cujo tipo satildeo outras classes Estes atributos que referenciam outros

tipos de classe satildeo o que costumamos chamar de dependecircncia

Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle

Se o nuacutecleo do Spring eacute chamado de Container de Inversatildeo de Controle (IoC de Inversion of Control em inglecircs)

porque estamos usando o termo injeccedilatildeo de dependecircncias Porque como bem observou Martin Fowler em seu artigo Inversion of Control Containers and the Dependency Injection Pattern 4 os containeres de inversatildeo de controle

como Spring Pico e outros aplicam um tipo muito especiacutefico de inversatildeo de controle

E neste momento uma segunda pergunta surge o que eacute inversatildeo de controle

Chama-se de inversatildeo de controle a teacutecnica de desenvolvimento na qual um

aspecto comportamental do sistema eacute delegado a uma entidade externa Um exemplo de inversatildeo de controle eacute o EJB O desenvolvedor implementa o

seu EJB e em seguida faz o deploy no servidor de aplicaccedilotildees sem precisar se preocupar com o modo como seu componente seraacute iniciado finalizado e

gerenciado porque neste caso eacute tudo feito pelo servidor Ao inveacutes de nos

preocuparmos com estas tarefas as delegamos a uma entidade externa que normalmente recebe o nome de container

A inversatildeo de controle esta no nuacutecleo do conceito de framework Ao

adotarmos um framework estamos reutilizando a estrutura de uma aplicaccedilatildeo

semi-pronta que finalizamos ao inserir nossos proacuteprios componentes

4 O artigo pode ser online neste endereccedilo httpwwwmartinfowlercomarticlesinjectionhtml

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

customizados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

dependecircncias acabariacuteamos com uma arquitetura similar agrave exposta na

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

FactoryDAOLivro

No novo modelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc

nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

fonte A partir destes dados ecomputacional o container eacute capaz de instanciar

instruamos a fazecirc-lo Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

consequumlecircncia temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees

Caso surja a necessidade de uma nova implementaccedilatildeo

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute

la como um arquivo jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s)necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

pendecircncias com Spring Framework 3

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute delegado

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido portanto que o termo Inversatildeo de Controle

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

com uma arquitetura similar agrave exposta na imagem 4

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das cnosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc-lo a partir de configuraccedilotildees que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

e usando o mecanismo de reflexatildeo provido pelocomputacional o container eacute capaz de instanciar e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees ja a necessidade de uma nova implementaccedilatildeo de alguma das abstraccedilotildees

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute-la jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s) de configuraccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara de ser executada

Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

delegado ao framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Inversatildeo de Controle eacute

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

imagem 4 Observe classes do

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

o ambiente e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolvedor se encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

de alguma das abstraccedilotildees

la distribuiacute-jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

ccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem-se desta maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

inversatildeo de dependecircncias cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle

Um moacutedulo de niacutevel mais

pertencente a um niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

contraacuterio Em nosso exemplo a classe

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

IDAOLivro O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo

Observe que as trecircs caracteriacute

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface

classe Cliente Como consequumlecircncia

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 versatildeo do sistema cuja ar

A mudanccedila foi sutil apenas explicitamos a presenccedila de um

classe Cliente do tipo IDAOLivro

Cliente3 Agora podemos dizer que atingimos o menor esta classe

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

classe FactoryDAOLivro que possui como dependecircncia tod

presentes no sistema da interface evolua chegaremos a um momento no qual a classe

2 Este beliacutessimo artigo encontra

httpwwwobjectmentorcompublicationsdippd3 Poderiacuteamos tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Imagem 3 - Terceira versatildeo do nosso modelo

pendecircncias com Spring Framework 3

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo Dependency Invertion Principle2 Este princiacutepio nos diz duas coisas

Um moacutedulo de niacutevel mais alto jamais deve depender diretamente de outro m niacutevel inferior mas sim de uma abstraccedilatildeo

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

Em nosso exemplo a classe Cliente eacute um moacutedulo de niacutevel superior natildeo

interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta i

mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trataobrigatoriedade de se implementar a funccedilatildeo buscaPorAutor

Observe que as trecircs caracteriacutesticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

em uma implementaccedilatildeo especiacutefica da interface IDAOLivro natildeo afetaraacute diretamente a

consequumlecircncia o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

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 estaacute longe do ideal porque aumentamos o Cliente Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

no segundo incluiacutemos outra que eacute a classe FactoryIDAOLivro

de apresentar uma terceira versatildeo do sistema cuja arquitetura eacute exposta na imagem 3

sutil apenas explicitamos a presenccedila de um atributo daoLivro

IDAOLivro cuja instacircncia eacute definida pelo construtor da classe

Agora podemos dizer que atingimos o menor grau de acoplamento possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

que possui como dependecircncia todas as implementaccedilotildees

presentes no sistema da interface IDAOLivro Eacute quase certo que conforme este sistema

evolua chegaremos a um momento no qual a classe FactoryDAOLivro se tornaraacute um

Este beliacutessimo artigo encontra-se acessiacutevel gratuitamente no endereccedilo

httpwwwobjectmentorcompublicationsdippdf tambeacutem ter criado um setter para este atributo poreacutem o efeito seria o mesmo

Terceira versatildeo do nosso modelo

O que vimos no segundo modelo eacute na realidade a aplicaccedilatildeo do princiacutepio de

cunhado por Robert C Martin em 1996 no seu artigo The

alto jamais deve depender diretamente de outro

Abstraccedilotildees natildeo devem depender de detalhes de implementaccedilatildeo mas sim o

eacute um moacutedulo de niacutevel superior natildeo lhe interessa como os tiacutetulos dos livros satildeo 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 implementaccedilatildeo especiacutefica (o arquivo no formato textual) Jaacute

na segunda passa a depender apenas de uma abstraccedilatildeo que no caso eacute a nossa interface

O segundo postulado tambeacutem foi respeitado no segundo modelo Observe que as

distintas implementaccedilotildees de IDAOLivro natildeo influenciam de forma alguma esta interface mas sim o contraacuterio No caso todas as implementaccedilotildees especiacuteficas de IDAOLivro

seguem rigidamente as regras definidas pela interface que no caso trata-se da

sticas presentes em um design ruim natildeo se aplicam no

segundo modelo Nosso software natildeo eacute mais fraacutegil pois caso seja feita qualquer alteraccedilatildeo

natildeo afetaraacute diretamente a

o sistema agora eacute mais faacutecil de ser mantido (natildeo haacute

rigidez) e ainda mais interessante obtivemos mobilidade pois podemos agora transportar

porque aumentamos o grau de Enquanto na primeira versatildeo sua uacutenica dependecircncia era a

FactoryIDAOLivro Eacute hora

imagem 3

daoLivro na cuja instacircncia eacute definida pelo construtor da classe

possiacutevel para

Poreacutem por mais que nos esforcemos se continuarmos seguindo esta linha de

raciociacutenio sempre nos depararemos com problemas de acoplamento Basta observar a

as as implementaccedilotildees

Eacute quase certo que conforme este sistema

se tornaraacute um

se acessiacutevel gratuitamente no endereccedilo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

monstro de difiacutecil manutenccedilatildeo A cada nova implementaccedilatildeo de IDAOLivro precisaremos alteraacute-la e compilaacute-la novamente

Aleacutem deste problema temos outro eacute necessaacuteria uma classe que crie uma instacircncia

de Cliente Esta por sua vez possui o mesmo problema apresentado no modelo 2 duas dependecircncias Resumindo chegamos ao limite do que podemos fazer usando apenas o padratildeo Factory

Entra a Injeccedilatildeo de Dependecircncias

A injeccedilatildeo de dependecircncias (Dependency Injection ou DI em inglecircs) eacute uma forma de

inversatildeo de controle na qual o aspecto a ser invertido eacute como o proacuteprio nome jaacute diz a resoluccedilatildeo de dependecircncias Ao inveacutes do desenvolvedor definir manualmente quais as

instacircncias a serem criadas e injetadas como fizemos nos trecircs modelos anteriormente descritos delega-se esta tarefa a um container de inversatildeo de controle (IoC) veja o quadro Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle - evitando assim a necessidade de se implementar o padratildeo 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 famiacutelia especiacutefica de

objetos Poreacutem como veremos no caso do Spring este factory vai aleacutem agrave medida que tambeacutem controla o ciclo de vida dos objetos por ele gerenciados Para introduzirmos o conceito imagine que este container eacute uma classe maacutegica que sempre nos retorna um

objeto cujo tipo eacute exatamente aquele que estamos precisando O truque por traacutes desta

maacutegica seraacute exposto no decorrer deste artigo O que eacute uma dependecircncia

Eacute muito raro encontrarmos um software real e uacutetil composto por uma uacutenica classe Na esmagadora maioria das

vezes topamos com classes que possuem atributos cujo tipo satildeo outras classes Estes atributos que referenciam outros

tipos de classe satildeo o que costumamos chamar de dependecircncia

Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle

Se o nuacutecleo do Spring eacute chamado de Container de Inversatildeo de Controle (IoC de Inversion of Control em inglecircs)

porque estamos usando o termo injeccedilatildeo de dependecircncias Porque como bem observou Martin Fowler em seu artigo Inversion of Control Containers and the Dependency Injection Pattern 4 os containeres de inversatildeo de controle

como Spring Pico e outros aplicam um tipo muito especiacutefico de inversatildeo de controle

E neste momento uma segunda pergunta surge o que eacute inversatildeo de controle

Chama-se de inversatildeo de controle a teacutecnica de desenvolvimento na qual um

aspecto comportamental do sistema eacute delegado a uma entidade externa Um exemplo de inversatildeo de controle eacute o EJB O desenvolvedor implementa o

seu EJB e em seguida faz o deploy no servidor de aplicaccedilotildees sem precisar se preocupar com o modo como seu componente seraacute iniciado finalizado e

gerenciado porque neste caso eacute tudo feito pelo servidor Ao inveacutes de nos

preocuparmos com estas tarefas as delegamos a uma entidade externa que normalmente recebe o nome de container

A inversatildeo de controle esta no nuacutecleo do conceito de framework Ao

adotarmos um framework estamos reutilizando a estrutura de uma aplicaccedilatildeo

semi-pronta que finalizamos ao inserir nossos proacuteprios componentes

4 O artigo pode ser online neste endereccedilo httpwwwmartinfowlercomarticlesinjectionhtml

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

customizados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

dependecircncias acabariacuteamos com uma arquitetura similar agrave exposta na

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

FactoryDAOLivro

No novo modelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc

nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

fonte A partir destes dados ecomputacional o container eacute capaz de instanciar

instruamos a fazecirc-lo Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

consequumlecircncia temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees

Caso surja a necessidade de uma nova implementaccedilatildeo

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute

la como um arquivo jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s)necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

pendecircncias com Spring Framework 3

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute delegado

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido portanto que o termo Inversatildeo de Controle

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

com uma arquitetura similar agrave exposta na imagem 4

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das cnosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc-lo a partir de configuraccedilotildees que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

e usando o mecanismo de reflexatildeo provido pelocomputacional o container eacute capaz de instanciar e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees ja a necessidade de uma nova implementaccedilatildeo de alguma das abstraccedilotildees

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute-la jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s) de configuraccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara de ser executada

Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

delegado ao framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Inversatildeo de Controle eacute

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

imagem 4 Observe classes do

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

o ambiente e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolvedor se encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

de alguma das abstraccedilotildees

la distribuiacute-jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

ccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem-se desta maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

monstro de difiacutecil manutenccedilatildeo A cada nova implementaccedilatildeo de IDAOLivro precisaremos alteraacute-la e compilaacute-la novamente

Aleacutem deste problema temos outro eacute necessaacuteria uma classe que crie uma instacircncia

de Cliente Esta por sua vez possui o mesmo problema apresentado no modelo 2 duas dependecircncias Resumindo chegamos ao limite do que podemos fazer usando apenas o padratildeo Factory

Entra a Injeccedilatildeo de Dependecircncias

A injeccedilatildeo de dependecircncias (Dependency Injection ou DI em inglecircs) eacute uma forma de

inversatildeo de controle na qual o aspecto a ser invertido eacute como o proacuteprio nome jaacute diz a resoluccedilatildeo de dependecircncias Ao inveacutes do desenvolvedor definir manualmente quais as

instacircncias a serem criadas e injetadas como fizemos nos trecircs modelos anteriormente descritos delega-se esta tarefa a um container de inversatildeo de controle (IoC) veja o quadro Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle - evitando assim a necessidade de se implementar o padratildeo 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 famiacutelia especiacutefica de

objetos Poreacutem como veremos no caso do Spring este factory vai aleacutem agrave medida que tambeacutem controla o ciclo de vida dos objetos por ele gerenciados Para introduzirmos o conceito imagine que este container eacute uma classe maacutegica que sempre nos retorna um

objeto cujo tipo eacute exatamente aquele que estamos precisando O truque por traacutes desta

maacutegica seraacute exposto no decorrer deste artigo O que eacute uma dependecircncia

Eacute muito raro encontrarmos um software real e uacutetil composto por uma uacutenica classe Na esmagadora maioria das

vezes topamos com classes que possuem atributos cujo tipo satildeo outras classes Estes atributos que referenciam outros

tipos de classe satildeo o que costumamos chamar de dependecircncia

Injeccedilatildeo de Dependecircncias ou Inversatildeo de Controle

Se o nuacutecleo do Spring eacute chamado de Container de Inversatildeo de Controle (IoC de Inversion of Control em inglecircs)

porque estamos usando o termo injeccedilatildeo de dependecircncias Porque como bem observou Martin Fowler em seu artigo Inversion of Control Containers and the Dependency Injection Pattern 4 os containeres de inversatildeo de controle

como Spring Pico e outros aplicam um tipo muito especiacutefico de inversatildeo de controle

E neste momento uma segunda pergunta surge o que eacute inversatildeo de controle

Chama-se de inversatildeo de controle a teacutecnica de desenvolvimento na qual um

aspecto comportamental do sistema eacute delegado a uma entidade externa Um exemplo de inversatildeo de controle eacute o EJB O desenvolvedor implementa o

seu EJB e em seguida faz o deploy no servidor de aplicaccedilotildees sem precisar se preocupar com o modo como seu componente seraacute iniciado finalizado e

gerenciado porque neste caso eacute tudo feito pelo servidor Ao inveacutes de nos

preocuparmos com estas tarefas as delegamos a uma entidade externa que normalmente recebe o nome de container

A inversatildeo de controle esta no nuacutecleo do conceito de framework Ao

adotarmos um framework estamos reutilizando a estrutura de uma aplicaccedilatildeo

semi-pronta que finalizamos ao inserir nossos proacuteprios componentes

4 O artigo pode ser online neste endereccedilo httpwwwmartinfowlercomarticlesinjectionhtml

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

customizados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

dependecircncias acabariacuteamos com uma arquitetura similar agrave exposta na

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

FactoryDAOLivro

No novo modelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc

nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

fonte A partir destes dados ecomputacional o container eacute capaz de instanciar

instruamos a fazecirc-lo Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

consequumlecircncia temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees

Caso surja a necessidade de uma nova implementaccedilatildeo

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute

la como um arquivo jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s)necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

pendecircncias com Spring Framework 3

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute delegado

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido portanto que o termo Inversatildeo de Controle

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

com uma arquitetura similar agrave exposta na imagem 4

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das cnosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc-lo a partir de configuraccedilotildees que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

e usando o mecanismo de reflexatildeo provido pelocomputacional o container eacute capaz de instanciar e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees ja a necessidade de uma nova implementaccedilatildeo de alguma das abstraccedilotildees

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute-la jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s) de configuraccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara de ser executada

Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

delegado ao framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Inversatildeo de Controle eacute

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

imagem 4 Observe classes do

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

o ambiente e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolvedor se encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

de alguma das abstraccedilotildees

la distribuiacute-jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

ccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem-se desta maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

customizados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

dependecircncias acabariacuteamos com uma arquitetura similar agrave exposta na

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

FactoryDAOLivro

No novo modelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc

nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

fonte A partir destes dados ecomputacional o container eacute capaz de instanciar

instruamos a fazecirc-lo Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

consequumlecircncia temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees

Caso surja a necessidade de uma nova implementaccedilatildeo

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute

la como um arquivo jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s)necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara

Imagem 4 - Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

pendecircncias com Spring Framework 3

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

nos lembramos do processo de preenchimento de formulaacuterios que eacute delegado

framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Apoacutes estes exemplos fica niacutetido portanto que o termo Inversatildeo de Controle

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

das dependecircncias das classes de nosso projeto

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

com uma arquitetura similar agrave exposta na imagem 4

que o Container natildeo possui nenhuma dependecircncia direta com nenhuma das cnosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

eacute feito pelo container que eacute instruiacutedo a fazecirc-lo a partir de configuraccedilotildees que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

e usando o mecanismo de reflexatildeo provido pelocomputacional o container eacute capaz de instanciar e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolved

encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

distribuir nas mais variadas situaccedilotildees ja a necessidade de uma nova implementaccedilatildeo de alguma das abstraccedilotildees

presentes no sistema tudo o que o desenvolvedor precisa fazer eacute implementaacute-la jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

sistema e em seguida alterar o(s) arquivo(s) de configuraccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem

maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

processo de recompilaccedilatildeo se torna uma tarefa muito mais rara de ser executada

Nosso modelo apoacutes aplicar Injeccedilatildeo de Dependecircncias

ados No caso de aplicaccedilotildees web este comportamento fica niacutetido quando

delegado ao framework ao inveacutes de ser implementado manualmente pelo desenvolvedor

Inversatildeo de Controle eacute

geneacuterico demais para ser adotado no caso do Spring aonde o foco eacute a resoluccedilatildeo

Voltando ao nosso exemplo inicial ao aplicarmos o padratildeo de injeccedilatildeo de

imagem 4 Observe classes do

nosso sistema Outro fator interessante a ser observado eacute a ausecircncia da classe

odelo todo o processo de instanciaccedilatildeo e preenchimento de dependecircncias

que podem estar nos mais variados formatos desde arquivos no formato XML ateacute anotaccedilotildees em coacutedigo

o ambiente e injetar todas as dependecircncias que noacutes o

Uma das grandes vantagens deste modelo eacute que neste estaacutegio o desenvolvedor se encontra proacuteximo do desacoplamento quase total entre seus componentes Como

temos sistemas com qualidade muito superior mais faacuteceis de manter e

de alguma das abstraccedilotildees

la distribuiacute-jar (ou class mesmo) incluir a implementaccedilatildeo no classpath do

ccedilatildeo do container sem a

necessidade de recompilar o sistema para se adequar a esta nova situaccedilatildeo Obteacutem-se desta maneira mobilidade total do sistema visto que com o nuacutecleo pronto e estabilizado o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Spring Framework entra em cena O objetivo do Spring Framework eacute simplificar o desenvolvimento de aplicaccedilotildees

corporativas Na imagem 5 podemos ver todos os moacutedulos que compotildeem o framework que eacute uma alternativa viaacutevel agrave plataforma Java Enterprise Edition Este incriacutevel

framework possibilitou usando apenas POJOs obter os mesmos resultados que ateacute entatildeo

soacute eram possiacuteveis com EJB E tudo isto graccedilas agrave aplicaccedilatildeo do conceito de injeccedilatildeo de

dependecircncias Spring pode fazer inuacutemeras coisas mas quando nos focamos apenas no seu nuacutecleo

percebemos que estamos lidando na realidade com um container de injeccedilatildeo de

dependecircncias e programaccedilatildeo orientada a aspectos leve Para melhor entender a sua

definiccedilatildeo conveacutem estudar suas partes Por que leve Spring eacute natildeo intrusivo Se sua aplicaccedilatildeo eacute baseada no Spring eacute

possiacutevel que suas classes natildeo venham a ter qualquer dependecircncia direta com o

framework Nada mais natural visto que o problema do alto acoplamento eacute justamente o

que o conceito de injeccedilatildeo de dependecircncias visa resolver Programaccedilatildeo orientada a aspectos O Spring oferece desde sua primeira versatildeo

suporte a programaccedilatildeo orientada a aspectos Esta eacute uma teacutecnica poderosa que permite ao

desenvolvedor separar a loacutegica de negoacutecios de serviccedilos de infra-estrutura presente em nossa aplicaccedilatildeo Eacute importante mencionar esta caracteriacutestica visto que se trata do outro pilar do framework aleacutem do container de injeccedilatildeo de dependecircncias

Poreacutem nosso foco eacute o container de injeccedilatildeo de dependecircncias Sendo assim iremos

tratar aqui apenas do moacutedulo Core Container do Spring Como seraacute visto eacute uma

ferramenta que consegue ser ao mesmo tempo extremamente poderosa e simples de se usar E esta eacute a beleza deste container

Imagem 5 Componentes do Spring Framework Nosso foco eacute no Core Container

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3

httpdevkicoitextocombr

O container de injeccedilatildeo de dependecircnciasChegou o momento de col

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

Para este artigo seraacute usada a versatildeo

modular Isto quer dizer quacompanham a distribuiccedilatildeo

As dependecircncias do Container

Iremos usar apenas os arquivos que compotildeem o

distribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo org

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

orgspringframework beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans Precisaremos portanto

expression A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficiallogging-[nuacutemero da versatildeo]jar em seu classpath

Como o container funciona

Para que o container seja uacutetil primeiro

suas configuraccedilotildees podem vir eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou

Uma vez alimentado com estas cointernamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas configuraccedilotildees como uma receita

instanciar um bean Estas receitas de beans no entanto

instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

especificam qual deve ser o tempo de vidaser removido do container De imediato o Spring nos fornece 5 tipos de escopo prototype request session e global session

visto que os demais satildeo usados no dese

foco do nosso artigo Na tabela 1

5 httpwwwspringframeworkorg 6 httpcommonsapacheorglogging7 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprio

Imagem 6 Funcionamento de um container

pendecircncias com Spring Framework 3

container de injeccedilatildeo de dependecircncias Chegou o momento de colocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial

seraacute usada a versatildeo 302 O Spring eacute um framework extremamente

modular Isto quer dizer que natildeo precisamos usar todos os arquivos JAR que

As dependecircncias do Container

usar apenas os arquivos que compotildeem o Core Container do Springdistribuiccedilatildeo oficial estes satildeo nomeados seguindo o seguinte padratildeo orgspringframework [nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

dos moacutedulos beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

que pode ser obtida em seu site oficial6 Deveraacute ser adicionado o arquivo commons

[nuacutemero da versatildeo]jar em seu classpath

er seja uacutetil primeiro precisamos configuraacute-lo No caso do Spring de basicamente trecircs fontes arquivos no formato XML (que

eacute a opccedilatildeo mais comum) anotaccedilotildees em coacutedigo fonte ou programaticamente7 alimentado com estas configuraccedilotildees o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

definem quais classes devem ser instanciadas suas interdependecircncias Pense nas receita a ser seguida pelo Spring quando for necessaacuterio

Estas receitas de beans no entanto dizem mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

qual deve ser o tempo de vida ou seja quando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo global session Destes apenas trataremos dos dois primeiros

visto que os demais satildeo usados no desenvolvimento de aplicaccedilotildees web o que foge do

tabela 1 eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

httpcommonsapacheorglogging - Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11

O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

desenvolvedor pode criar os seus proacuteprios parsers de configuraccedilatildeo caso seja de seu interesse

Funcionamento de um container

ocar toda esta teoria em praacutetica Para usar o container de

injeccedilatildeo do Spring eacute necessaacuterio baixar a uacuteltima versatildeo do framework em seu site oficial5 302 O Spring eacute um framework extremamente

e natildeo precisamos usar todos os arquivos JAR que

do Spring Na springframework

[nome do moacutedulo][nuacutemero da versatildeo]RELEASEjar Sendo assim o arquivo

beans302RELEASEjar por exemplo eacute na realidade o moacutedulo

beans context contextsupport core e

A uacutenica dependecircncia externa do container eacute a biblioteca Commons Logging

Deveraacute ser adicionado o arquivo commons-

No caso do Spring trecircs fontes arquivos no formato XML (que

o container iraacute armazenar

internamente representaccedilotildees dos objetos a serem gerenciados Estas representaccedilotildees

Pense nas g quando for necessaacuterio

mais do que apenas quais classes instanciar e suas interdependecircncias definem tambeacutem o escopo de cada bean Escopos

uando um bean jaacute instanciado deveraacute

De imediato o Spring nos fornece 5 tipos de escopo singleton Destes apenas trataremos dos dois primeiros

nvolvimento de aplicaccedilotildees web o que foge do

eacute possiacutevel conhecer a descriccedilatildeo destes 5 escopos

Na escrita deste artigo a uacuteltima versatildeo disponiacutevel eacute a 11 O nuacutecleo do Spring eacute totalmente desacoplado de uma fonte especiacutefica de configuraccedilotildees Sendo assim o

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Tabela 1 Escopos do Spring

Escopo Descriccedilatildeo

singleton Trata-se do escopo default do Spring O container manteacutem uma

uacutenica instacircncia do bean definido prototype O Spring sempre retorna uma nova instacircncia do bean caso o

mesmo seja requerido request Usado em aplicaccedilotildees web define que a instacircncia do bean possuiraacute

o mesmo tempo de vida que uma requisiccedilatildeo HTTP session Adotado em aplicaccedilotildees web define que a instacircncia do bean se

encontraraacute armazenada na sessatildeo do usuaacuterio sendo imediatamente

destruiacutedo junto com esta global session Tambeacutem usado em aplicaccedilotildees web armazena a instacircncia do bean

em uma sessatildeo global

Configurado e pronto para o uso entra a classe cliente que simplesmente faraacute

requisiccedilotildees ao container do Spring por um bean especiacutefico

Instanciando o Container

O Spring oferece dois tipos de container BeanFactory e ApplicationContext Nossa primeira boa praacutetica portanto diz respeito a qual tipo deveraacute ser selecionado

BeanFactory eacute na realidade uma interface presente no pacote

orgspringframeworkbeansfactory que representa o container mais simples fornecido pelo framework oferecendo apenas suporte a injeccedilatildeo de dependecircncias e gerenciamento

de ciclo de vida dos beans O framework jaacute vem com algumas implementaccedilotildees desta interface sendo a mais

usada orgspringframeworkbeansfactoryxmlXmlBeanFactory que lecirc as configuraccedilotildees

do container a partir de um documento XML Normalmente opta-se por usar o BeanFactory quando o ambiente computacional

oferece restriccedilotildees mais incisivas como por exemplo um Applet Jaacute ApplicationContext que tambeacutem eacute uma interface presente no pacote

orgspringframeworkcontext eacute uma extensatildeo de BeanFactory e oferece todos os serviccedilos

deste e mais alguns como internacionalizaccedilatildeo extensibilidade e gerenciamento de

eventos As implementaccedilotildees mais usadas desta interface satildeo

ClassPathXmlApplicationContext e FileSystemXmlApplicationContext Ambas consomem suas configuraccedilotildees a partir de documentos no formato XML e encontram-se no pacote orgspringframeworkcontextsupport A diferenccedila entre uma e outra eacute apenas

aonde os documentos XML se encontram Enquanto a primeira o busca no classpath da aplicaccedilatildeo a outra o encontra no sistema de arquivos no qual a aplicaccedilatildeo eacute executada

Na esmagadora maioria das vezes vocecirc acabaraacute usando ApplicationContext a

natildeo ser que possua excelentes razotildees para natildeo fazecirc-lo Sendo assim no transcorrer deste artigo usaremos apenas ApplicationContext

Haacute uma diferenccedila de comportamento entre BeanFactory e ApplicationContext No caso do ApplicationContext todos os beans com escopo singleton satildeo automaticamente

carregados por default ao contraacuterio de BeanFactory em que beans pertencentes a este escopo soacute satildeo inicializados na primeira vez em que satildeo requeridos Esta eacute uma das razotildees

pelas quais se costuma usar BeanFactory

Oculte seu Container Uma das principais vantagens do Spring eacute ser leve sendo assim devemos proteger

esta caracteriacutestica ao maacuteximo possiacutevel De preferecircncia apenas uma classe deveraacute

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

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

Listagem 1 Ocultando o Container de Injeccedilatildeo de Dependecircncias

public class Container private ApplicationContext contextoSpring private ApplicationContext getContextoSpring() if (contextoSpring == null) contextoSpring = new ClassPathXmlApplicationContext(dispringxml) return contextoSpring public Object getBean(String nome) ApplicationContext contexto = getContextoSpring() if (contexto = null) try return contextogetBean(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 instanciaccedilatildeo do container eacute caro do ponto de vista computacional

Sendo assim eacute interessante mantermos uma uacutenica instacircncia de nosso ApplicationContext o que conseguimos a partir da implementaccedilatildeo do padratildeo singleton na classe Container Assim garantimos que uma uacutenica instacircncia do container seraacute usada durante todo o

processo de execuccedilatildeo do nosso sistema O que eacute Padratildeo de Projeto Singleton

O padratildeo de projeto Singleton tem como objetivo garantir que uma uacutenica instacircncia de uma classe seja

criada aleacutem de tambeacutem fornecer um uacutenico ponto de acesso a mesma Seu uso eacute um tanto quanto

controverso sendo normalmente usado apenas em situaccedilotildees como a exposta na listagem 1 deste artigo

Na listagem 1 tambeacutem vemos basicamente tudo o que vocecirc precisa saber a respeito

de como obter um bean gerenciado pelo container Basta executar a funccedilatildeo getBean que recebe como paracircmetro o nome do bean presente no container Seu valor de retorno eacute do

tipo Object Se no container natildeo houver um bean com este nome seraacute disparada uma

exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException razatildeo pela qual lidamos com esta exceccedilatildeo dentro da funccedilatildeo getBean

Observe que a classe Container possui apenas um uacutenico meacutetodo puacuteblico no caso

getBean Isto nos ajuda a garantir que nenhuma outra classe do projeto venha a ter uma dependecircncia 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 eacute neste momento que a configuraccedilatildeo entra em cena Tal como dito

anteriormente haacute basicamente trecircs maneiras de se configurar o Spring atraveacutes de

documentos no formato XML usando anotaccedilotildees ou programaticamente

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Cada uma destas abordagens apresenta suas vantagens e desvantagens que veremos no transcorrer deste artigo poreacutem dada sua natureza eacute interessante comeccedilar pela

configuraccedilatildeo via XML pois esta expotildee todos os recursos do Spring que seratildeo expostos

no restante deste artigo Na listagem 2 podemos ver como nossa aplicaccedilatildeo inicial pode

ser configurada usando este formato

Listagem 2 Configuraccedilatildeo do Spring de nossa aplicaccedilatildeo Inicial

ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsdgt ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt ltbean id=daoLivro class=diDAOLivroTexto scope=prototypegt ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbeansgt

O elemento raiz do documento eacute beans Cada bean gerenciado pelo container eacute

definido pela tag bean Na listagem 2 podemos ver nossa aplicaccedilatildeo configurada para

trabalhar com um uma implementaccedilatildeo de IDAOLivro que usa como fonte de dados um

arquivo textual O atributo bean possui apenas um atributo obrigatoacuterio que eacute o class que especifica

qual classe deveraacute ser instanciada O atributo id eacute 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 aplicaccedilatildeo da injeccedilatildeo de dependecircncias No interior

da tag bean que o representa haacute a tag property Esta tag possui o atributo obrigatoacuterio

name que identifica qual o nome da propriedade que deveraacute ser atribuiacuteda pelo container Spring utiliza o padratildeo JavaBeans Sendo assim a classe Cliente deveraacute 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 eacute o

nome do bean que deveraacute ser injetado que no caso eacute o bean daoLivro Eacute interessante observar que a tag property tambeacutem eacute 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 livrostxt usando o

atributo value Caso o atributo seja do tipo numeacuterico o Spring se encarregaraacute de fazer a

conversatildeo necessaacuteria para o usuaacuterio

Listagem 3 A classe Cliente

public class Cliente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao public void buscar(String valor) ListltStringgt titulos = getDaoLivro()getLivrosAutor(valor) for (String titulo titulos) Systemoutprintln(titulo) public Cliente() public Cliente(IDAOLivro dao) setDaoLivro(dao)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Os tipos de injeccedilatildeo de dependecircncia

No Spring a injeccedilatildeo de dependecircncias pode ser feita de duas formas por setter ou

construtor Acima acabamos de ver a injeccedilatildeo por setter Este tipo de injeccedilatildeo eacute executado

em duas etapas Na primeira o construtor default da classe definida par ao bean eacute

executado gerando uma nova instacircncia para em seguida serem executados os setters

definidos pelas tags property presentes no interior da tag bean Sendo assim quando for adotar a injeccedilatildeo de dependecircncias por setter eacute obrigatoacuteria a presenccedila do construtor

default Jaacute a injeccedilatildeo de dependecircncias por construtor eacute feita definindo-se qual construtor

deveraacute ser executado ao criarmos uma nova instacircncia do bean A listagem 4 expotildee como

o mesmo efeito que obtivemos usando a injeccedilatildeo por setter pode ser obtido ao adotarmos a

injeccedilatildeo por construtor

Listagem 4 Injeccedilatildeo de dependecircncias por construtor

ltDefinindo o construtor por tipo ltbean id=clientePorTipo class=diClientegt

ltconstructor-arg type=diIDAOLivro ref=daoLivrogt ltbeangt

ltDefinindo pela ordem do atributo do construtor ltbean id=clientePorOrdem class=diClientegt ltconstructor-arg index=0 ref=daoLivrogt ltbeangt

Para fazer a injeccedilatildeo por construtor usamos a tag constructor-arg Haacute duas opccedilotildees

para se definir quais os valores de cada atributo do construtor A mais recomendada eacute por

tipo Neste caso constructor-arg deveraacute receber um atributo chamado type (tal como na listagem 4) que identifique qual o tipo do argumento O segundo atributo poderaacute ser tanto

ref caso estejamos referenciando outro bean quanto value se estivermos nos referindo a um atributo primitivo ou string

A segunda opccedilatildeo eacute definir os valores dos atributos do construtor a partir de sua ordem Na listagem 4 podemos ver como isto eacute feito no bean clientePorOrdem No caso ao inveacutes de usarmos o atributo type usamos index que define qual atributo a partir da sua ordem (sempre iniciando a partir do zero) Esta opccedilatildeo eacute uacutetil para se evitar ambiguumlidade na escolha do construtor caso haja mais de um paracircmetro pertencente a um mesmo tipo

Injeccedilatildeo por setter ou construtor

Como regra geral opta-se pela injeccedilatildeo por construtores para as dependecircncias

obrigatoacuterias e injeccedilatildeo por setter para as dependecircncias opcionais Os puristas preferem a

injeccedilatildeo por construtores porque assim temos a garantia de que ao obtermos um bean

estamos lidando com uma instacircncia completa com todas as dependecircncias obrigatoacuterias

preenchidas No entanto a equipe de desenvolvimento do Spring incentiva a injeccedilatildeo por setter

pois assim evita-se a criaccedilatildeo de construtores com vaacuterios atributos alguns dos quais definindo inclusive dependecircncias opcionais Eacute uma maneira de influenciar os

desenvolvedores a evitarem a escrita destes construtores que acabam dificultando a manutenccedilatildeo

Outra vantagem da injeccedilatildeo por setter eacute que ela nos permite reconfigurar a instacircncia

apoacutes obtida visto que tudo o que o desenvolvedor precisa fazer eacute passar uma nova

dependecircncia ao setter em questatildeo Se a pergunta vou precisar alterar alguma

dependecircncia de minha instacircncia apoacutes obtida for positiva a injeccedilatildeo por setter deveraacute ser

adotada

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Dando nome aos beans

Natildeo precisamos nomear um bean Caso natildeo o faccedilamos o proacuteprio Spring iraacute criar

um nome interno para o bean mapeado e caso este bean sem nome seja o uacutenico de seu

tipo isto eacute o uacutenico bean pertencente a determinada classe podemos inclusive obtecirc-lo usando o meacutetodo sobrescrito getBean(Class classe) do ApplicationContext

Mas esta obviamente natildeo eacute a melhor alternativa Afinal de contas nosso sistema

pode crescer e outros beans pertencentes agrave mesma classe podem acabar no nosso arquivo

de configuraccedilatildeo E neste caso ao tentar obter um bean pela sua classe ao inveacutes de pelo

seu nome obteriacuteamos uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException nos informando que haacute mais de um bean mapeado para aquele tipo especiacutefico

Sendo assim eacute fundamental saber como dar nome aos nossos beans A classe bean possui dois atributos para que possamos executar esta tarefa O primeiro deles jaacute vimos

nas listagens 2 e 4 Trata-se do atributo id Usamos este atributo quando queremos definir um nome uacutenico para nossos beans

Ao definirmos este atributo para o bean garantimos que em nosso container soacute poderaacute

existir um bean como aquele nome Eacute uma boa praacutetica usaacute-lo por outra razatildeo alguns

parseadores de XML oferecem otimizaccedilotildees para este atributo o que pode nos

proporcionar ganhos em performance e validaccedilatildeo destes documentos visto que o atributo id eacute o mesmo definido na especificaccedilatildeo do formato XML pelo W3C

Nossa outra opccedilatildeo eacute o atributo name que nos permite dar um ou mais nomes para um bean Eacute tambeacutem usado quando eacute necessaacuterio nomear um bean usando caracteres

especiais o que natildeo eacute permitido na especificaccedilatildeo XML No caso de um bean possuir mais

de um nome estes podem ser separados por espaccedilo ponto e viacutergula () ou viacutergulas () Na

listagem 5 podemos ver alguns exemplos

Listagem 5 Um bean com mais de um nome

ltbean name=clienteexemplo class=diClientegtltbeangt ltbean name=cliente exemplo class=diClientegtltbeangt ltbean name=clienteexemplo class=diClientegtltbeangt

Eacute comum oferecer mais de um nome a um determinado bean em projetos maiores

nos quais possam ocorrer situaccedilotildees nas quais times diferentes trabalhem em subsistemas distintos a serem integrados Poreacutem na esmagadora maioria das vezes o ideal eacute que cada

bean possua um uacutenico nome a fim de se evitar excessos de nomenclatura que acabem por

gerar confusotildees dentro da equipe Eacute uma boa praacutetica adotar padrotildees de nomenclatura aos beans Um padratildeo bastante

adotado eacute 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 padratildeo de projeto

DAO

Modularizando a configuraccedilatildeo

Uma das principais criacuteticas agrave configuraccedilatildeo no formato XML eacute a extensatildeo que estes

documentos possam vir a tomar Realmente eacute um tanto trabalhoso dar manutenccedilatildeo em

arquivos gigantescos poreacutem eacute possiacutevel sanar este problema dividindo a configuraccedilatildeo em

arquivos distintos Nestes casos cada arquivo de configuraccedilatildeo pode representar uma

camada loacutegica do sistema ou um moacutedulo de sua arquitetura Haacute duas maneiras de se modularizar a configuraccedilatildeo A primeira delas eacute atraveacutes da

tag ltimportgt que pode ser inserida em seus documentos XML tal como exemplificado na listagem 6

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Listagem 6 Usando a tag ltimportgt

ltbeansgt ltimport resource=servicosxmlgt ltimport resource=daodaosxmlgt ltbean id=cliente class=diClientegt ltbeansgt

A tag import possui o atributo obrigatoacuterio resource que define qual arquivo deveraacute

ser importado para a configuraccedilatildeo do Spring Os caminhos dos arquivos a serem

importados sempre satildeo relativos ao do arquivo que estaacute fazendo a importaccedilatildeo Sendo

assim se o arquivo da listagem 6 estivesse dentro do classpath do sistema no diretoacuterio

direcursos o arquivo importado servicosxml tambeacutem estaria neste mesmo diretoacuterio e

daosxml se encontraria no path direcursosdao O outro modo de obter o mesmo resultado eacute usando um construtor especial

oferecido tanto por ClassPathXmlApplicationContext quanto FileSystemApplicationContext que recebe como paracircmetros um array de strings

fornecendo os caminhos para os arquivos de configuraccedilatildeo a serem usados A listagem 7 exemplifica este processo usando a classe ClassPathXmlApplicationContext

Listagem 7 Modularizando a configuraccedilatildeo com o construtor especial String[] arquivos = direcursosspringxml direcursosservisosxml direcursosdaodaosxml ApplicationContext contextoSpring = new ClassPathXmlApplicationContext(arquivos)

Dentre as duas opccedilotildees a princiacutepio eacute mais interessante a primeira visto que natildeo eacute

necessaacuterio recompilar o coacutedigo fonte caso seja necessaacuterio adicionar algum novo arquivo

de configuraccedilatildeo ao container No entanto a segunda opccedilatildeo se mostra interessante em

situaccedilotildees nas quais a escolha dos arquivos de configuraccedilatildeo envolvam alguma loacutegica

interna do seu sistema

Escopo Singleton vs Prototype

Por padratildeo todo bean gerenciado pelo Spring possui escopo singleton Eacute

fundamental compreender a diferenccedila entre os dois escopos baacutesicos 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 encarregaraacute de manter uma uacutenica instacircncia deste bean sobre seu controle Sendo

assim toda vez que estivermos chamando o bean cliente definido na listagem 2 estaremos obtendo a mesma instacircncia da classe diCliente No entanto eacute importante

observar que estamos lidando aqui com um singleton relativo visto que nada impede que criemos fora do container uma instacircncia diferente desta mesma classe chamando seu

construtor padratildeo por exemplo Um fator que precisa ser levado em conta eacute que o BeanFactory e o

ApplicationContext adotam poliacuteticas diferentes com relaccedilatildeo a beans com escopo

singleton Quando o ApplicationContext eacute inicializado por padratildeo todos os beans com

escopo singleton satildeo instanciados e possuem suas dependecircncias injetadas ao passo que no BeanFactory estes soacute seratildeo preparados no momento em que forem chamados pela primeira vez

Jaacute no caso do prototype sempre que pedirmos ao container um bean que pertenccedila a

este escopo obteremos uma nova instacircncia Isto nos traacutes um certo impacto na

performance visto que sempre ocorreraacute o processo de preparaccedilatildeo do bean que eacute

composto por duas etapas instanciaccedilatildeo do mesmo e injeccedilatildeo das dependecircncias Na praacutetica utiliza-se o padratildeo singleton para beans mais complexos e que natildeo

armazenem estado como por exemplo a classe SessionFactory do Hibernate Uma situaccedilatildeo para a qual eacute necessaacuterio ficar atento eacute quando um bean com escopo

singleton possui uma dependecircncia com escopo prototype Eacute preciso ter consciecircncia de

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

que a injeccedilatildeo de dependecircncias em um bean soacute eacute feita no momento em que o bean eacute

instanciado Sendo assim a dependecircncia com escopo prototype injetada no bean singleton

apenas uma vez Se vocecirc quiser no entanto que o seu bean com escopo singleton sempre obtenha

uma nova instacircncia de sua dependecircncia com escopo prototype uma soluccedilatildeo eacute tornar este

bean consciente da existecircncia do container de injeccedilatildeo de dependecircncias Esta natildeo eacute uma

boa praacutetica pois estamos adicionando peso ao Spring visto que agora uma classe de

negoacutecios da nossa aplicaccedilatildeo passa a possuir uma dependecircncia direta com o container de

injeccedilatildeo de dependecircncias Mas caso seja de fato necessaacuterio basta que sua classe implemente a interface

orgspringframeworkcontextApplicationContextAware tal como a versatildeo alternativa da classe Cliente que encontra-se exposta na listagem 8

Listagem 8 um bean com consciecircncia do container de injeccedilatildeo de dependecircncias public class Cliente implements ApplicationContextAware o restante da classe eacute igual private ApplicationContext applicationContext public ApplicationContext getContextoSpring() return applicationContext public void setApplicationContext(ApplicationContext ac) throws BeansException thisapplicationContext = ac

O container do Spring iraacute injetar nas classes que implementem a interface

ApplicationContextAware uma instacircncia de si mesmo chamando o meacutetodo

setApplicationContext que recebe como paracircmetro uma instacircncia e ApplicationContext Sendo assim internamente a classe pode pedir ao container que sempre lhe retorne uma nova instacircncia de uma de suas dependecircncias cujo escopo seja singleton

Inicializaccedilatildeo tardia de beans singleton

Tal como falamos na seccedilatildeo anterior o ApplicationContext por default prepara todos

os beans com escopo singleton no momento em que eacute carregado Tal comportamento nem

sempre eacute adequado visto que haacute situaccedilotildees nas quais alguns beans satildeo usados somente em

circunstacircncias muito especiacuteficas Sendo assim porque carregaacute-los se talvez nem sejam necessaacuterios durante a execuccedilatildeo do sistema

A soluccedilatildeo para o problema eacute simples Basta adicionarmos o atributo lazy-init agrave tag

bean com o valor true Agora o bean soacute seraacute processado no momento em que for

requerido pela primeira vez Eacute possiacutevel incluir o atributo lazy-init na tag bean tambeacutem

assim altera-se o comportamento default de carregamento para todos os beans presentes naquele arquivo de configuraccedilatildeo

No entanto nem sempre esta eacute uma boa praacutetica Enquanto o sistema estiver em

desenvolvimento eacute interessante que todos os beans sejam carregados visto que assim seraacute possiacutevel encontrar erros de configuraccedilatildeo nesta etapa inicial do processo facilitando

assim a correccedilatildeo de erros

Autowiring

O container de injeccedilatildeo de dependecircncias do Spring pode automaticamente descobrir

quais as dependecircncias de um bean a partir de um recurso bastante interessante chamado

autowiring Como vantagem o desenvolvedor pode reduzir significativamente o nuacutemero

de propriedades e construtores que precisa especificar em seus arquivos de configuraccedilatildeo

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

O funcionamento do autowiring inicia-se quando marcamos um bean para que seja auto injetado8 pelo container Quando este bean for ser iniciado o container iraacute varrer

todos os atributos presentes em sua classe e para cada um verificaraacute entre as definiccedilotildees

de beans armazenada em seu interior a existecircncia de um bean que possa ser injetado

naquele ponto Encontrados todos os candidatos apropriados estes satildeo injetados no bean

Caso haja alguma ambiguumlidade o container natildeo saberaacute qual bean deve ser injetado e neste caso uma exceccedilatildeo do tipo orgspringframeworkbeansfactoryNoSuchBeanDefinitionException informando qual atributo natildeo pode ser injetado

A melhor maneira de entender este conceito eacute vecirc-lo em praacutetica Na listagem 9

podemos ver como configurar o Spring para tirar proveito deste recurso Podemos ver trecircs

beans definidos daoLivro cliente e autowired O primeiro seraacute injetado nos demais

Enquanto na definiccedilatildeo do bean cliente precisamos definir todas as dependecircncias

manualmente o mesmo natildeo eacute verdade com o bean autowired Repare que natildeo foi

necessaacuterio incluir em sua definiccedilatildeo nenhum construtor ou propriedade apenas o atributo

autowire com o valor byType Listagem 9 Usando autowiring ltbeansgt ltbean id=daoLivro class=diDAOLivroTextogt

ltproperty name=arquivo value=livrostxtgt ltbeangt

ltbean id=cliente class=diClientegt ltproperty name=daoLivro ref=daoLivrogt ltbeangt

ltbean name=autowired class=diCliente autowire=byTypegt ltbeangt

ltbeansgt

Quando lidamos com este recurso nosso principal oponente eacute a ambiguumlidade Se na

listagem 9 houvesse mais um bean do tipo diDAOLivroTexto nos deparariacuteamos com um erro no momento em que o bean autowired fosse iniciado pelo container pois este natildeo

saberia qual bean injetar na propriedade daoLivro do bean autowired Uma das ferramentas que possuiacutemos para evitar estes problemas satildeo os modos

fornecidos pelo Spring para encontrar automaticamente as dependecircncias 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 - Estrateacutegias de auto injeccedilatildeo de dependecircncias

Modo Descriccedilatildeo

no Comportamento default Desabilita a auto injeccedilatildeo de dependecircncias

para o bean byName O container iraacute buscar por dependecircncias que possuam o mesmo

nome que a propriedade a ser injetada Sendo assim na listagem 9 poderiacuteamos ter definido a auto injeccedilatildeo usando esta estrateacutegia que

funcionaria sem problemas Caso natildeo hajam beans com o mesmo

nome presentes entre as definiccedilotildees do container a exceccedilatildeo NoSuchBeanDefinitionException

byType A busca por dependecircncias seraacute por tipo O container iraacute buscar por

beans que sejam do mesmo tipo que a dependecircncia a ser injetada Havendo mais de uma possibilidade seraacute disparada uma exceccedilatildeo do tipo NoSuchBeanDefinitionException

constructor Eacute anaacuteloga agrave estrateacutegia byType A Diferenccedila eacute que seraacute feita a

injeccedilatildeo de dependecircncias a partir dos construtores do bean

8 O termo em inglecircs que poderia ser adotado ao inveacutes de auto injetado seria autowired

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

autodetect Seguindo esta estrateacutegia o container iraacute primeiro buscar executar a

injeccedilatildeo de dependecircncias por construtor Se for encontrado um

construtor default no bean o container passaraacute a adotar a estrateacutegia

byType

Deve-se usar a auto injeccedilatildeo de dependecircncias apenas em projetos de pequeno e meacutedio porte visto que trata-se de um processo bem menos preciso que a injeccedilatildeo expliacutecita

atraveacutes da definiccedilatildeo de propriedades e construtores Apesar do Spring se esforccedilar ao

maacuteximo para fazer a escolha correta podem haver situaccedilotildees nas quais uma injeccedilatildeo

incorreta seja feita Sendo assim seu uso normalmente eacute desencorajado em projetos maiores a natildeo ser que sejam adotadas regras riacutegidas na nomenclatura dos beans e sua

tipagem Caso queira diminuir ainda mais a quantidade de configuraccedilatildeo a ser digitada eacute

possiacutevel definir o comportamento de auto injeccedilatildeo default do container adicionando o

atributo default-autowire agrave tag beans com um dos valores presentes na tabela 2 Assim todos os beans nela contidos seguiratildeo a mesma poliacutetica

Para aumentar a precisatildeo da injeccedilatildeo automaacutetica podemos tambeacutem excluir

candidatos agrave injeccedilatildeo incluindo o atributo autowire-candidate com o valor false na tag bean do componente que queremos remover do processo de busca

Outra possibilidade interessante eacute dar preferecircncia a uma dependecircncia especiacutefica

adicionando o atributo primary com valo true agrave tag bean correspondente Em situaccedilotildees

nas quais ocorram mais de uma possibilidade de escolha este seraacute privilegiado no

processo ajudando assim a diminuir a possibilidade de ambiguumlidade no processo de auto injeccedilatildeo de dependecircncias

Poreacutem estas duas alternativas acabam por tornar mais complexo o processo de

criaccedilatildeo dos arquivos de configuraccedilatildeo Por esta razatildeo eacute uma boa praacutetica simplesmente natildeo

usar o autowiring em projetos de grande porte

Callbacks de Ciclo de Vida

Haacute situaccedilotildees nas quais natildeo basta apenas injetar as dependecircncias de um bean e

definir seu escopo Satildeo casos nos quais para que um bean esteja pronto para uso seja

necessaacuterio algum preacute-processamento interno antes que o mesmo seja fornecido ao objeto que o solicitou ao container Aleacutem disto haacute momentos nos quais eacute necessaacuterio que o

proacuteprio bean libere os recursos que usou durante sua existecircncia Spring nos oferece dois eventos que podemos customizar no ciclo de vida de nossos

beans inicializaccedilatildeo que eacute executado logo apoacutes todas as dependecircncias de um bean terem

sido injetadas e destruiccedilatildeo executado apenas apoacutes o container que gerencia o bean ter

sido destruiacutedo O callback de inicializaccedilatildeo pode ser adicionado ao bean de duas maneiras A

primeira delas eacute a implementaccedilatildeo da interface

orgspringframeworkbeansfactoryInitializingBean Esta conteacutem um uacutenico meacutetodo do

tipo chamado afterPropertiesSet() que dispara uma exceccedilatildeo geneacuterica Na listagem 10 haacute

um exemplo de sua implementaccedilatildeo Este procedimento natildeo eacute recomendado pois acopla o

bean ao Spring Framework violando assim um dos principais objetivos do framework que eacute justamente sua natildeo intrusatildeo nas classes do sistema

Listagem 10 Implementando callbacks de inicializaccedilatildeo e destruiccedilatildeo no coacutedigo fonte import orgspringframeworkbeansfactoryDisposableBean import orgspringframeworkbeansfactoryInitializingBean public class ClienteCallbacks implements InitializingBean DisposableBean public void afterPropertiesSet() throws Exception Systemoutprintln(Todas as dependecircncias injetadas)

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

public void destroy() throws Exception Systemoutprintln(Container destruido)

A outra opccedilatildeo eacute incluir na tag bean o atributo init-method O valor do atributo deve

ser o nome de um meacutetodo definido no bean que natildeo possua atributos e que pode ou natildeo

disparar alguma exceccedilatildeo Esta eacute a abordagem adequada visto que assim garantimos que

nosso bean natildeo esteja diretamente acoplado ao Spring Framework Jaacute o callback de destruiccedilatildeo tambeacutem pode ser adicionado usando basicamente os

mesmos procedimentos que adotamos par ao callback de inicializaccedilatildeo Podemos

implementar a interface DisposableBean que nos obrigaraacute a implementar o meacutetodo destroy() tal como fizemos na listagem 10 ou se preferirmos podemos tambeacutem

adicionar o atributo destroy-method agrave tag bean correspondente O valor do deste atributo deveraacute ser um meacutetodo que natildeo possua paracircmetros Como no caso do callback de

inicializaccedilatildeo esta eacute a abordagem favorita por evitar o acoplamento de nossas classes ao coacutedigo do Spring Framework

Haacute um detalhe que precisa ser mencionado o callback de destruiccedilatildeo natildeo eacute

executado jamais em beans cujo escopo seja prototype pois uma vez criado este bean natildeo estaacute mais sobre o poder do container de injeccedilatildeo de dependecircncias sendo assim eacute

impossiacutevel que o container venha a executar os meacutetodos de destruiccedilatildeo nestes beans

Alimentando o Container com Anotaccedilotildees Uma alternativa ao XML que apareceu pela primeira vez no Spring 20 eacute o uso das

anotaccedilotildees Trata-se de um caminho bastante interessante para os que gostam de ver suas configuraccedilotildees proacuteximas ao coacutedigo fonte ou sentem-se incomodados com a necessidade de se escrever documentos XML

O problema com as anotaccedilotildees eacute que elas aumentam o peso do Spring ao acoplar nossas classes ao Spring Framework Como veremos eacute possiacutevel diminuir este

acoplamento ao adotarmos anotaccedilotildees baseadas em JSRs poreacutem mesmo assim estaremos

aumentando o acoplamento de nossas classes o que natildeo ocorreria se estiveacutessemos adotando configuraccedilotildees puramente baseadas em XML Outro problema eacute que a

necessidade de se recompilar coacutedigo ao adicionarmos novos componentes ao nosso

sistema aumenta significativamente Poreacutem as anotaccedilotildees natildeo excluem completamente o XML Na realidade XML e

anotaccedilotildees convivem perfeitamente bem em um mesmo sistema Voltando ao nosso

sistema inicial uma versatildeo alternativa baseada em anotaccedilotildees precisaria de um arquivo de

configuraccedilatildeo tal como o exposto na listagem 11

Listagem 11 Configurando o container para trabalhar com anotaccedilotildees ltxml version=10 encoding=ISO-8859-1gt ltbeans xmlns=httpwwwspringframeworkorgschemabeans xmlnsxsi=httpwwww3org2001XMLSchema-instance xmlnscontext=httpwwwspringframeworkorgschemacontext xsischemaLocation=httpwwwspringframeworkorgschemabeans httpwwwspringframeworkorgschemabeansspring-beans-30xsd httpwwwspringframeworkorgschemacontext httpwwwspringframeworkorgschemacontextspring-context-30xsdgt ltcontextannotation-configgt ltcontextcomponent-scan base-package=dianotadosgt ltbean id=daoLivro class=diDAOLivroTexto scope=prototype primary=truegt ltproperty name=arquivo value=livrostxtgt ltbeangt ltbeansgt

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Como pode ser observado na listagem 11 ainda estou mapeando um bean usando XML Foi feito propositalmente para expor como as duas abordagens anotaccedilotildees e XML

convencional convivem perfeitamente lado a lado Comparando a listagem 11 com a listagem 2 observa-se a inclusatildeo de um novo namespace context Eacute fundamental que este

seja declarado para que o Spring possa trabalhar com anotaccedilotildees Haacute tambeacutem duas novas tags ltcontextannotation-configgt informa o container que

seratildeo usadas configuraccedilotildees baseadas em anotaccedilotildees aleacutem do XML convencional Outra tag

importante eacute ltcontextcomponent-scangt Esta instrui o container a no momento em que for inicializado varrer todas as classes contidas no pacote dianotados em busca dos beans a serem gerenciados pelo container

O leitor atento tambeacutem observaraacute a ausecircncia do bean cliente Nesta versatildeo

alternativa do nosso sistema este bean seraacute configurado usando apenas anotaccedilotildees Sendo

assim implementamos uma classe chamada ClienteComponente exposta na listagem 12 Esta classe expotildee praticamente todas as configuraccedilotildees que expusemos na seccedilatildeo dedicada

agrave configuraccedilatildeo baseada em XML Dado que os conceitos baacutesicos da injeccedilatildeo de dependecircncias foi dado na seccedilatildeo em

que tratamos da configuraccedilatildeo proveniente de documentos em formato XML nosso foco agora seraacute em expor os equivalentes daquela configuraccedilatildeo ao adotarmos o modelo de

configuraccedilotildees baseadas em anotaccedilotildees

Listagem 12 A classe ClienteComponente import diIDAOLivro import javaxannotationPostConstruct import javaxannotationPreDestroy import javaxannotationResource import orgspringframeworkcontextannotationScope import orgspringframeworkstereotypeComponent Scope(prototype) Component(clienteAnotado) public class ClienteComponente private IDAOLivro daoLivro public IDAOLivro getDaoLivro() return thisdaoLivro Resource(name=daoLivro) public void setDaoLivro(IDAOLivro dao) thisdaoLivro = dao PostConstruct public void init() Systemoutprintln(Fui construido E meu dao eacute + getDaoLivro()getClass()) PreDestroy public void destroy() Systemoutprintln(Meu container foi destruido)

Identificando beans com Component

Ao varrer o pacote dianotados o container iraacute buscar todas as classes que possuam

a anotaccedilatildeo Component Esta equivale agrave tag bean que vimos anteriormente Como boa praacutetica eacute interessante passar como paracircmetro para esta classe um valor do tipo string que

nomeie nosso bean Caso natildeo seja feito o container iraacute criar um nome interno para o

bean poreacutem este seria de pouca valia para noacutes pois um bean realmente uacutetil eacute aquele que

possamos usar e para usaacute-lo este precisa ser nomeado Pense nesta anotaccedilatildeo como a dica que enviamos ao container para que identifique

uma de nossas classes como um bean a ser gerenciado

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Definindo o escopo com Scope

A anotaccedilatildeo Scope eacute o equivalente ao atributo scope da tag bean Se omitido seraacute

adotado o escopo padratildeo do Spring que tal como jaacute mencionado eacute o Singleton Esta

anotaccedilatildeo recebe como paracircmetro o nome do escopo que iremos adotar Na listagem 12 soacute

para variar adotamos o escopo prototype

Definindo dependecircncias com Resource

Anotaccedilotildees tambeacutem possuem um relativo para a tag property No caso estamos

falando da anotaccedilatildeo Resource que deve ser aplicada sobre atributos ou setters de

nossas classes Este atributo recebe como paracircmetro o nome do bean que desejamos seja

injetado em nosso bean Eacute interessante observar que esta anotaccedilatildeo natildeo eacute nativa do Spring mas sim da JSR-

250 cujo objetivo eacute definir anotaccedilotildees para conceitos semacircnticos em comum presentes nas

plataformas Java SE e EE Sendo assim ao usarmos esta anotaccedilatildeo estamos na realidade

evitando mais uma ligaccedilatildeo direta com classes do Spring o que eacute uma praacutetica interessante

visto que no futuro caso seja necessaacuterio trocar o container de injeccedilatildeo de dependecircncias

esta tarefa se tornaraacute 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 configuraccedilatildeo baseada em XML

possuiacutemos as anotaccedilotildees Autowired e Inject Autowired eacute a anotaccedilatildeo provida pelo

Spring Sendo assim ao adotaacute-la devemos ter em mente que estamos incluindo uma dependecircncia direta ao Spring Framework em nosso coacutedigo fonte Jaacute a anotaccedilatildeo Inject

faz parte da JSR-330 que especifica o mecanismo de injeccedilatildeo de dependecircncia padratildeo para

a plataforma Java Sendo assim o uso de Inject eacute preferiacutevel ao de Autowired pois

assim estamos criando uma dependecircncia com um padratildeo Java e natildeo algo tatildeo especiacutefico

quanto o Spring Na listagem 13 podemos ver um exemplo da aplicaccedilatildeo de Autowired em mais

uma versatildeo de nosso bean cliente assim eacute possiacutevel expor mais uma diferenccedila entre

AutoWired e Inject No caso Autowired possui um atributo adicional chamado required que aceita um valor booleano Quando definido como true caso natildeo seja

encontrado o bean a ser injetado uma exceccedilatildeo seraacute disparada pelo container de injeccedilatildeo de

dependecircncias Esta opccedilatildeo eacute uacutetil quando a aplicaccedilatildeo estaacute em desenvolvimento pois permite aos

desenvolvedores encontrar problemas antes que o sistema entre em produccedilatildeo

Listagem 13 Usando Autowired import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowired import orgspringframeworkstereotypeComponent Component(clienteAnotadoAutowired) public class ClienteComponenteAutoWired Autowired(required=true) private IDAOLivro dao public IDAOLivro getDaoLivro() return dao public void setDaoLivro(IDAOLivro dao) thisdao = dao

Callbacks de inicializaccedilatildeo e destruiccedilatildeo com PostConstruct e PreDestroy

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Na listagem 12 podemos ver a aplicaccedilatildeo das anotaccedilotildees PostConstruct e

PreDestroy que equivalem aos atributos init-method e destroy-method que vimos na configuraccedilatildeo baseada em XML

Seu uso natildeo poderia ser mais simples inclua PostConstruct no meacutetodo sem

paracircmetros que deveraacute ser executado apoacutes ter sido feita a injeccedilatildeo de dependecircncias em seu

bean para identificar o callback de inicializaccedilatildeo e PreDestroy no meacutetodo sem

paracircmetros que deveraacute ser executado no momento em que o container de injeccedilatildeo de

dependecircncias for ser destruiacutedo

Quando o XML anula as anotaccedilotildees

Ao ser inicializado o container do Spring primeiro carrega as configuraccedilotildees

provenientes de anotaccedilotildees para em seguida processar as configuraccedilotildees em formato XML

Sendo assim eacute importante que o leitor saiba que caso um bean seja configurado

inicialmente usando anotaccedilotildees e este mesmo bean esteja especificado no formato XML as configuraccedilotildees no segundo formato anularatildeo a primeira

Este eacute um erro muito comum em times que tenham optado por trabalhar com os

dois formatos poreacutem pode ser visto tambeacutem como uma alternativa viaacutevel quando se deseja anular configuraccedilotildees em cima das quais natildeo possuiacutemos controle como por exemplo as que estatildeo presentes em classes jaacute compiladas presentes no classpath de nosso

sistema

Limitaccedilotildees das anotaccedilotildees

Atualmente configuraccedilotildees baseadas em anotaccedilotildees natildeo permitem que seja mapeado

mais de um bean para uma mesma classe tal como fizemos na listagem 4 Caso seja necessaacuterio que isto seja feito o desenvolvedor possui apenas duas alternativas ou mapeia

apenas um bean usando anotaccedilotildees para uma classe e o restante usando XML ou faz todo o trabalho usando apenas XML

Dentre as duas alternativas a segunda eacute uma melhor praacutetica visto que assim expotildee

para o time todas as variantes do bean para todos os membros da equipe de uma forma mais expliacutecita evitando assim problemas de comunicaccedilatildeo dentro do time

Outra limitaccedilatildeo das anotaccedilotildees eacute que elas natildeo nos permitem definir o valor de

atributos primitivos ou listas tal como podemos fazer facilmente no caso do XML

Configuraccedilatildeo baseada em Java (100 livre de XML) No Spring 30 foi introduzido um novo tipo de contexto de aplicaccedilatildeo chamado

AnnotationConfigApplicationContext que pela primeira vez possibilita ao desenvolvedor configurar um container de injeccedilatildeo de dependecircncias do Spring sem a presenccedila de

qualquer arquivo XML pois toda configuraccedilatildeo eacute feita via coacutedigo Trata-se de uma alternativa bastante poderosa que pode ser usada em situaccedilotildees nas

quais os beans gerenciados pelo container natildeo possam ser definidos apenas

declarativamente como fizemos usando apenas anotaccedilotildees ou XML Agora podemos

incluir loacutegica neste processo de uma maneira bastante simples Visto que todos os conceitos referentes ao processo de gerenciamento de beans jaacute

foi tratado nas seccedilotildees anteriores deste artigo iremos ver aqui apenas como mapear os beans usando este novo recurso de uma maneira raacutepida comparando-o com as maneiras anteriores

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

Apresentando Configuration e Bean

Antes de tratarmos da classe AnnotationConfigApplicationContext iremos ver o que

o alimenta no caso as anotaccedilotildees Configuration e Bean aplicadas a POJOs Na

listagem 14 podemos ver a aplicaccedilatildeo destas anotaccedilotildees

Listagem 14 Aplicando as anotaccedilotildees Configuration e Bean import diCliente import diDAOLivroSGBD import diDAOLivroTexto import diIDAOLivro import orgspringframeworkbeansfactoryannotationAutowire import orgspringframeworkcontextannotationBean import orgspringframeworkcontextannotationConfiguration Configuration public class BeanSource Bean(name=daoLivro) public IDAOLivro getDAOLivro() return new DAOLivroTexto() Bean(name=cliente) public Cliente getCliente() Cliente saida = new Cliente() saidasetDaoLivro(getDAOLivro()) return saida Bean(name=clienteSGBD) public Cliente getClienteSGBD() Cliente saida = new Cliente() saidasetDaoLivro(new DAOLivroSGBD()) return saida Bean(name=clienteAutowired autowire=AutowireBY_TYPE) public Cliente getClienteAutowired() return new Cliente()

Tabela 3 - Atributos de Bean

Atributo Descriccedilatildeo

name O nome dado ao bean que seraacute retornado autowire Qual poliacutetica de autowiring que seraacute adotada pelo container

Valores possiacuteveis AutowireBY_TYPE AutowireBY_NAME AutowireNO gt Desabilita o autowiring e eacute o valor default

initMethod Nome do meacutetodo que deveraacute ser invocado no bean apoacutes este ter

suas dependecircncias injetadas destroyMethod Nome do meacutetodo que deveraacute ser invocado quando o container que

gerencia o bean for destruiacutedo A classe presente na listagem 14 eacute o que chamamos de Configuration ou seja uma

classe anotada com Configuration e que possui funccedilotildees anotadas com a anotaccedilatildeo

Bean que produzem beans que seratildeo gerenciados pelo container de injeccedilatildeo de

dependecircncias do Spring Sendo assim para criar uma classe de configuraccedilatildeo tudo o que o desenvolvedor

precisa fazer eacute anotaacute-la com Configuration e em seguida implementar uma ou mais funccedilotildees anotadas com Bean cujos atributos encontram-se listados na tabela 3

Autowiring

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

A primeira impressatildeo que temos quando nos deparamos com este novo recurso eacute

que natildeo precisaremos mais da injeccedilatildeo automaacutetica de dependecircncias visto que estamos

manualmente criando nossos beans Felizmente isto natildeo eacute verdade Para ativar o

autowiring basta definir o valor do paracircmetro autowire com o valor AutowireBY_NAME ou AutowireBY_TYPE tal como exposto na tabela 3

Observando a listagem 14 vemos que o autowiring eacute aplicado no meacutetodo

getClienteAutowired() usando a estrateacutegia por tipo

Definindo o escopo Novamente aqui o padratildeo do Spring se aplica Se natildeo for definido explicitamente

qual o escopo do bean este seraacute interpretado como pertencente ao escopo singleton Para que o bean possua um escopo

Callbacks de Inicializaccedilatildeo e Destruiccedilatildeo

Tal como na configuraccedilatildeo baseada em XML como na configuraccedilatildeo baseada em

anotaccedilotildees tambeacutem podemos definir os callbacks de inicializaccedilatildeo e destruiccedilatildeo A

diferenccedila eacute que os definimos com os atributos initMethod e destroyMethod presentes na anotaccedilatildeo Bean Exatamente como nos casos anteriores eles devem conter o nome de

um meacutetodo que natildeo possua atributos presentes na classe do bean a ser retornado

Apresentando o container AnnotationConfigApplicationContext

A classe que possibilita a configuraccedilatildeo baseada em Java eacute

AnnotationConfigApplicationContext que se encontra no pacote orgspringframeworkcontextannotation Para usaacute-la no entanto eacute necessaacuterio adicionar

duas dependecircncias externas ao seu projeto No caso as bibliotecas CGLIB e ASM9 que satildeo usadas para manipular bytecode em tempo de execuccedilatildeo

Haacute dois modos de se alimentar as configuraccedilotildees de

AnnotationConfigApplicationContext O desenvolvedor pode criar uma nova instacircncia

desta classe passando uma uacutenica classe de configuraccedilatildeo ou um array de classes de

configuraccedilatildeo ou programaticamente As duas maneiras podem ser vistas na listagem 15

Listagem 15 Alimentando AnnotationConfigApplicationContext AnnotationConfigApplicationContext contexto = null Alimentando com uma uacutenica classe de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass) Alimentando com um array de classes de configuraccedilatildeo contexto = new AnnotationConfigApplicationContext(BeanSourceclass DataSourcesclass) Alimentando o context programaacuteticamente contexto = new AnnotationConfigApplicationContext() contextoregister(BeanSourceclass) apoacutes adicionar todas as classes ao contexto execute obrigatoacuteriamente o meacutetodo refresh() contextorefresh()

Conclusotildees Como pudemos ver o container de injeccedilatildeo do Spring eacute uma ferramenta bastante

rica que nos permite resolver de maneira elegante o problema do alto acoplamento em nossos sistemas Tal como dito na introduccedilatildeo eacute importante conhecer o conceito de

9 A biblioteca CGLIB (Code Generation Library) pode ser obtida em seu site oficial

httpcglibsourceforgenet Para este artigo foi usada a versatildeo 22 Jaacute a biblioteca ASM pode ser obtida

em httpasmow2org Usamos neste artigo a versatildeo 32

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software

Guia itexto Injeccedilatildeo de Dependecircncias com Spring Framework 3 httpdevkicoitextocombr

injeccedilatildeo de dependecircncias mesmo que o Spring jamais seja usado porque seu conhecimento torna explicita a principal causa de designs ruins de aplicaccedilatildeo

Poreacutem caso o Spring venha a ser adotado eacute importante que a sua natildeo intrusatildeo seja

mantida o maacuteximo possiacutevel pois caso contraacuterio podemos acabar voltando ao problema do

alto acoplamento Tal como exposto no artigo conseguimos manter esta leveza a partir da adoccedilatildeo de configuraccedilatildeo no formato XML ou Java e no caso das anotaccedilotildees adotando ao

maacuteximo possiacutevel apenas anotaccedilotildees que sejam parte de alguma JSR ao contraacuterio das que

fazem parte do core do Spring O mais interessante no entanto eacute a constataccedilatildeo do poder que o conceito de injeccedilatildeo

de dependecircncias 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

Referecircncias httpwwwspringframeworkorg Site oficial do Spring Framework httpstaticspringsourceorgspringdocs30xspring-framework-referencehtml -

Documentaccedilatildeo de referecircncia do Spring Framework 30 httpwwwobjectmentorcompublicationsdippdf - Artigo The Dependency

Injection Principle de Robert C Martin httpwwwmartinfowlercomarticlesinjectionhtml - Artigo Inversion of Control

Containers and the Dependency Injection pattern de Martin Fowler que cunhou o termo

Injeccedilatildeo de Dependecircncias

Henrique Lobo Weissmann (o Kico) (kicoloboitextonet) eacute consultor GroovyGrails

fundador do Grails Brasil e soacutecio da itexto Desenvolvimento de Projetos

(httpwwwitextocombr) que atua na criaccedilatildeo de projetos adotando software livre e muito

Grails Aleacutem disto em seu blog (httpdevkicoitextocombr) expotildee sua experiecircncia no

desenvolvimento de software