Spring Framework Parte 1 -> Dependency Injection
Quem é dessa área e nunca ouviu falar de Spring Framework por favor levante a mão………….. Ótimo, todo mundo pelo menos já ouviu falar desse tal de Spring.
Durante esta série de tutoriais eu vou demonstrar o que é, pra que server e como vc pode utilizar o Spring para facilitar seus projetos.
Primeiramente, o que é esse tal de Spring afinal de contas? Spring é um framework que propicia um container para sua aplicação, ou seja, sua aplicação roda em cima do container do Spring. Tal container provê principalmente a Injeção de Dependência (ou Inversão de Controle, como era conhecido anteriormente) e a Programação Orientada a Aspectos.
Nesta primeira parte eu vou falar sobre o padrão Injeção de Dependência e os benefícios que ele provê. Vamos lá então:
O padrão de projeto Injeção de Dependência diz que uma classe não deve criar as suas dependências, em outras palavras, uma classe não deve instanciar seus atributos. Ao invés disso, eles devem ser injetados na classe através de um mecanismo externo, ou através de quem criou o objeto desta classe.
Ainda não está claro né… Vamos a um exemplo (baseado em um dos exemplos do livro Spring in Action 2, 2008) para facilitar as coisas.
Vamos imaginar que fomos contratados para desenvolver o software do Ídolos Spring?, uma competição de talentos musicais onde as pessoas cantam e/ou tocam. Primeiro de tudo vamos desenvolver uma interface genérica o suficiente para todos os nossos competidores:
public interface Competidor public void apresentar(); }
Pronto, agora todo mundo que for competir no Ídolos Spring vai ter que implementar essa interface para poder participar (é quase como se fosse a inscrição da competição… hahahahah péssima analogia..
).
Vamos então aos competidores, vamos começar com um cantor. Um cantor não toca nenhum instrumento musical, ele apenas canta uma música. Vamos então à interface que descreve uma música:
public interface Musica public void cantar(); }
Baseado na interface, já podemos criar uma música:
public class AtireiOPauNoGato implements Musica { private static String[] letra = { "Atirei o páu no gato tô tô", "Mas o gato tô tô", "Não morreu reu reu", "Dona Chica cá", "Admirou-se se", "Do berro, do berro que o gato deu", "Miau !!!!!!"}; public void cantar() { for (int i = 0; i < letra.length; i++) { System.out.println(letra[i]); } } }
Legal, alguém vai cantar a famosa cantiga Atirei o pau no gato. Vamos codificar o cantor que irá fazer isso então:
public class Cantor implements Competidor { private Musica musica; public Cantor() { this.musica = new AtireiOPauNoGato(); } public void apresentar() { musica.cantar(); } }
Prontinho. Agora toda vez que um cantor for se apresentar ele irá cantar Atirei o Pau no Gato. Mas pera ai, tem alguma coisa que não faz muito sentido aqui não tem?
Será que TODO cantor da nossa competição vai cantar a mesma música? Acho que não né… E do jeito que esta classe está implementada, nós temos que mudar a classe para ele cantar uma outra musica. Isso não é lá muito viável…
O que a Injeção de Dependência prega é que ao invés de o cantor se preocupar em ficar preparando a música que ele vai cantar, ele apenas vai receber a música impressa um pouco antes da competição e pronto.
Pensando nisso, o cantor ficaria assim:
public class Cantor implements Competidor { private Musica musica; public Cantor() { } public void setMusica(Musica musica) { this.musica = musica; } public void apresentar() { musica.cantar(); } }
Pronto, o cantor já não está mais preparando a sua música, pouco antes da apresentação ele vai receber a música (através do setter) e vai cantá-la (porque quem é bom faz ao vivo! hehehe).
Ok ok, até aqui não teve absolutamente NADA do tal do Spring, e vc provavelmente ainda não entendeu o porque desse monte de interfaces que parecem bobas não é mesmo?…
Vamos lá, advinhem quem vai dar a musica para o cantor? EXATO!! O container do Spring é quem vai ser responsável por entregar a música para o nosso cantor, ou em termos mais técnicos, o container é quem faz toda a linkagem dos beans (cada objeto manipulado pelo container é um bean, ex: uma musica, um cantor, um objeto que acessa o banco de dados, etc).
Para nós vermos como isso tudo funciona (pq ngm gosta de bla bla bla), vou abrir o NetBeans 6.8, criar uma nova Aplicação Java e criar as interfaces e classes descritas até aqui.
O NetBeans já traz as bibliotecas do Spring Framework junto com a IDE, o que te economiza um tempinho baixando-as. Clique com o botão direito na pasta Bibliotecas e cliquem “Adicionar bliblioteca…” e adicione a biblioteca “Spring Framework 2.5″
Uma vez que o Spring já está no classpath nós já podemos criar um arquivo de configuração para descrever os beans da nossa aplicação. Toda a configuração do container é feita através de arquivos XML.
Sendo assim eu criei mais um pacote (conf) e criei o arquivo idolos.xml dentro dele, este será o arquivo que o Spring irá utilizar para o container da nossa aplicação.
A tag root dos arquivos de configuração do Spring é a tag <beans> que define os namespaces e os DTDs necessários. De começo deixe o arquivo assim:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> </beans>
Essa é a estrutura básica de um arquivo de configuração (não se assuste com o tamanho dessa tag, vc não precisa decorar essas coisas).
Já que nossas classes estão prontas, vamos para o nosso primeiro competidor: José. O José vai cantar Atirei o Pau no Gato. Para declará-lo e dar a música pra ele vai ficar assim:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="atireiopau" class="injecaodependencia.AtireiOPauNoGato" /> <bean id="jose" class="injecaodependencia.Cantor"> <property name="musica" ref="atireiopau" /> </bean> </beans>
Aqui é que o Spring começa a trabalhar, cada tag
Em termos de código, seria como se o container fizesse o seguinte:
injecaodependencia.AtireiOPauNoGato atireiopau = new injecaodependencia.AtireiOPauNoGato(); injecaodependencia.Cantor jose = new injecaodependencia.Cantor(); jose.setMusica(atireiopau);
Essa é a mágica da Injeção de Dependência, o José teve a música “injetada” nele, se a gente quiser que ele cante outra música não precisamos reescrever a classe Cantor, apenas injetar uma música diferente nele.
Isso torna a aplicação muito mais desacoplada, muito mais fácil de testar e de reusar os módulos!!!
Mas e para usar isso agora? Como que a gente põe isso pra funcionar? Eu quero ver o José cantar!!!! hehehe
Vamos lá então, vamos ao código da classe principal do nosso exemplo:
public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/idolos.xml"); Competidor competidor = (Competidor) ctx.getBean("jose"); competidor.apresentar(); } }
A interface ApplicationContext é justamente o container (um dos existentes) do Spring Framework. Existe também a BeanFactory mas essa é bem mais simples e eu não irei comentá-la.
O que acontece nesse código então é o seguinte: é criado o container passando o arquivo de configuração que ele irá utilizar, depois é recuperado o bean “jose” do container (nesse momento o container instancia o bean e todas as suas dependências) e por fim, nós pedimos pro José se apresentar.
Você deverá ver ele cantando incrivelmente bem o clássico Atirei o Pau no Gato.
Porém o próximo competidor promete! Ele irá cantar E tocar Ciranda Cirandinha com uma gaita!! Essa eu quero ver!!
Vamos às classes necessárias para o próximo competidor:
public class CirandaCirandinha implements Musica { private static String[] letra = { "Ciranda , cirandinha,", "Vamos todos cirandar,", "Vamos dar a meia volta,", "Volta e meia vamos dar", "", "O anel que tu me destes,", "Era vidro", "E se quebrou.", "O amor que tu me tinhas", "Era pouco e se acabou.", "", "Ciranda , cirandinha,", "Vamos todos cirandar,", "Vamos dar a meia volta,", "Volta e meia vamos dar"}; public void cantar() { for (int i = 0; i < letra.length; i++) { System.out.println(letra[i]); } } }
public interface Instrumento { public void tocar(); }
public class Gaita implements Instrumento { public void tocar() { System.out.println("FUU FUU FII FII"); } }
public class CantorTocador extends Cantor { private Instrumento instrumento; public CantorTocador() { super(); } public void setInstrumento(Instrumento instrumento) { this.instrumento = instrumento; } public void apresentar() { instrumento.tocar(); super.apresentar(); instrumento.tocar(); } }
Pronto, agora nosso próximo competidor está pronto para se apresentar. Sras e Srs dêem as boas vindas para Carlos:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="atireiopau" class="injecaodependencia.AtireiOPauNoGato" /> <bean id="jose" class="injecaodependencia.Cantor"> <property name="musica" ref="atireiopau" /> </bean> <bean id="ciranda" class="injecaodependencia.CirandaCirandinha" /> <bean id="gaita" class="injecaodependencia.Gaita" /> <bean id="carlos" class="injecaodependencia.CantorTocador"> <property name="musica" ref="ciranda" /> <property name="instrumento" ref="gaita" /> </bean> </beans>
Agora basta chamar o Carlos para se apresentar ao invés do José:
public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/idolos.xml"); Competidor competidor = (Competidor) ctx.getBean("carlos"); competidor.apresentar(); } }
E se a gente quisesse que o Carlos tocasse piano cantando Atirei o Pau no Gato? Simples:
public class Piano implements Instrumento { public void tocar() { System.out.println("PLIN PLIN PLIN"); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="atireiopau" class="injecaodependencia.AtireiOPauNoGato" /> <bean id="jose" class="injecaodependencia.Cantor"> <property name="musica" ref="atireiopau" /> </bean> <bean id="ciranda" class="injecaodependencia.CirandaCirandinha" /> <bean id="gaita" class="injecaodependencia.Gaita" /> <bean id="piano" class="injecaodependencia.Piano" /> <bean id="carlos" class="injecaodependencia.CantorTocador"> <property name="musica" ref="atireiopau" /> <property name="instrumento" ref="piano" /> </bean> </beans>
Basta “injetar” os beans desejados nas dependências e boa! Tudo segue seu fluxo natural.
Esta foi uma pequena (eu diria mínima) introdução à Injeção de Dependências no Spring Framework. O container ApplicationContext possui muuuuuito mais funções para gerenciar os seus beans, porém isso iria extender demais este assunto.
Acho que se você leu o post até aqui, vc conseguiu pegar o que eu quis passar: programar utilizando interfaces torna o seu código muito mais limpo, fácil de entender, fácil de dar manutenção, fácil de reutilizar, fácil de extender, ou seja, melhora tudo!!
Adicionando isso com a técnica de Injeção de Dependência torna a aplicação altamente desacoplada em termos de componentes (você pode utilizar a classe Cantor em qualquer outra aplicação, só precisa passar uma classe que implemente a interface Musica pra ele e tudo vai funcionar perfeitamente).
Os códigos fontes utilizados neste tutorial estão aqui.
[]s e até a próxima,
Saab.


40 Responses so far
Aurelio
setembro 13th, 2010
12:04
Parabéns pela matéria! Excelente! Sua abordagem torna o assunto divertido e o aprendizado flui bem mais facilmente.
Saab
setembro 13th, 2010
15:12
Valeu Aurelio.
Muito bom saber que você gostou e aprendeu com essa matéria.
=]
Lucas
setembro 14th, 2010
9:27
Muito obrigado, me ajudou muito, só sofri um pouco por você ter usado o NetBeans, mas quando eu finalmente consegui configurar no Eclipse…
Parabéns pela post!
Saab
setembro 20th, 2010
15:08
Fico contente que você conseguiu captar a essência do assunto cara..
E parabéns a você por conseguir configurar a IDE…
=)
LuiVilella
outubro 4th, 2010
22:18
Muito didático parabéns Excelente abordagem, muito obrigado , pessoas como você fazem Java valer a pena. Parabens!!!
Júlio
outubro 26th, 2010
17:08
Lembrou a serie Use a Cabeça.
Muito bom o post, explicou de forma simples e objetiva. Parabéns.
Fred Chevitarese
novembro 8th, 2010
15:12
Gostei muito do seu artigo
Parabéns!!!
Saab
novembro 13th, 2010
22:13
Obrigado pelo feedback galera!
Fico muito feliz que tenham gostado. =]
Jjose
novembro 19th, 2010
0:09
Simples e objetivo, usei esse exemplo p/ os maneh s
Mateus
novembro 19th, 2010
15:32
Será que vale a pena dar uma olhada no Bean Factory também?
Saab
novembro 21st, 2010
14:52
Mateus,
Alguns recursos avançados que o ApplicationContext usa não estão presentes no BeanFactory, o que o torna um container ainda mais leve, podendo rodar em ambientes com menos recursos disponíveis (memória, processador, hadrware em geral).
É legal dar uma olhada para saber até onde vale a pena usar o BeanFactory, em outras palavras, caso sua aplicação use apenas as funcionalidades que estão presentes no BeanFactory, pode ser mais interessante utilizá-lo para não tornar sua aplicação um pouco mais pesada a troco de nada.
Bruno
janeiro 31st, 2011
14:20
Parabéns pelo artigo, finalmente percebi (em português) a explicação do conceito Dependency Injection.
Um abraço desde Portugal!
Roberto
fevereiro 1st, 2011
21:45
Saab,
Parabéns pela série de posts sobre Spring. De forma irreverente e muito didática você conseguiu explicar um assunto que possuí complexidade razoável para iniciantes.
Obrigado
Roberto
Saab
fevereiro 1st, 2011
22:01
Fico muito feliz em saber que estão conseguindo entender o assunto!
Mto boa sorte na continuação do estudo de vocês e passem de tempos em tempos por aqui que irão encontrar coisas novas!
=]
Renato
fevereiro 24th, 2011
17:26
Boa Materia.
Muito diferente da maioria dos tutorias, este é bem pratico.
Obrigado.
Cristiano
março 21st, 2011
8:23
Meu caro, parabéns pelo texto, extremamente didático, claro e fácil de entender! Sua abrodagem foi brilhante!
Sucesso pra você, e obrigado por compartilhar seu conhecimento conosco!
Saab
março 22nd, 2011
19:07
Obrigado pelo feedback pessoal! =]
Paulo Eduardo
março 24th, 2011
14:55
Cara, você é um gênio da didática! hehehe…. parabéns velho, com certeza existem pessoas por aí que sabem bem mais que você mas nem chegam perto da tua capacidade de transmitir o que sabe. Com certeza você aprendeu com tutoriais e livros nem tão bem escritos, mas na hora de transmitir pensou mais nos outros. Continue escrevendo, parabéns!
felipe
maio 6th, 2011
0:52
Parabéns, realmente você tem uma ótima didática!! Gostaria de ter lido este post antes, tive que aprender isso batendo a cabeça na mesa, lembro do artigo que eu li pra começar entender inversão de controle…. eu achava que era uma coisa de outro mundo…. dai eu aprendi e fiquei com vontade de bater no cara que escreveu…
aeuhaeueahueauheahue
parabéns, ficou muito bom!
Rodrigo
maio 15th, 2011
23:11
Cara eu achei esse artigo no google na sexta a noite, mas como tava cansado não li inteiro, apenas adicionei nos favoritos. No sabado de manhã sai q nem um louco procurando um livro de spring pois toh precisando aprender para trabalhar. Comprei o livro spring em ação. Agora li o artigo inteiro (q por sinal me deu uma boa idéia do que é injeção de dependencia) e vejo q vc cita o livro q comprei. Acho q fiz uma boa escolha então neh?? Cara seu artigo ficou muito bom. Ajudou bastante.
Saab
maio 16th, 2011
22:46
Obrigado e parabéns pela aquisição!
O livro é ótimo para quem está começando. =]
[],
Saab
heitor
maio 31st, 2011
20:50
Muito bom cara, esses tutoriais sobre spring vão me ajudar.
Valeu
shen
junho 27th, 2011
10:48
cara, parabens cutrti muito o tutorial.. spring como todo Framework é dificil de entender no começo, mas vc ajudou muito nas duvidas…
valeeu!
Eric Lessa
julho 11th, 2011
16:51
Kra estou aqui pra desenterrar o artigo, como estou estudando agora Spring achei o artigo muito bom, bem explicado e de fácil compreensão, descontraído também hehe, Parabéns pelo trabalho e a vontade de compartilhar seus conhecimentos.
Saab
julho 12th, 2011
20:47
Valew pelo feedback pessoal!
Sempre bom saber que estão aprendendo com meus posts. =D
Voltem sempre. hehehe
Jackson William
julho 15th, 2011
11:19
Rapaz, sou novato na linguagem java, estou correndo atras de muitas coisas e me deparei com esta explicação e putzz, muito massa meu velho.
Parabéns pelo POST e muito obrigado por compartilhar o conhecimento. Ficou muito claro para mim.
Luana
agosto 10th, 2011
16:17
Oi Saab,
Vc é muito didático PARABÉNS… adorei!
Beijos…
Alexandre
outubro 3rd, 2011
11:49
Saab,
Excelente!
Rogerio
novembro 1st, 2011
11:29
Fantastico cara, nunca tinha visto seu site, mas já estou lendo tudo aqui. Vc explica muito bem, e manja muito do q ta falando. Meus parabens!
Yuri
novembro 4th, 2011
3:53
Eu pensei que nunca entenderia esse assunto, mas agora ta tudo beleza. Valeu!!!
Thiago Marinho
novembro 5th, 2011
14:11
Eaew Saab =D blz? Vlw pelo post, muito didático, divertido, gostei muito de ler, vou ler a “série” completa de Spring, estou precisando fazer um projeto na disciplina de Web, estava pensando em usar Ejb, que sei um pouquinho, mas quero aprender Spring tbm, por isso escolhi ele, vou precisar do recurso de IoC (Injeção de Dependência) que ele possui, e vou fazer o projeto utilizando JPA com Hibernate e a camada de controle/visão com JSF 2.0. Logo, utilizarei: Spring + Hibernate + JSF 2.0. Vlw abraços!
Saab
novembro 6th, 2011
12:04
Fala Thiago,
Boa sorte com o teu projeto e qualquer coisa pode ficar a vontade para postar dúvidas relacionadas aos posts aqui no blog.
=]
Robson Quaresma
dezembro 6th, 2011
10:55
Ótimo tutorial Saab, parabéns!!!
Joel Sousa
dezembro 6th, 2011
22:05
Excelente! Gostei muito =D
Francisco Alves
dezembro 22nd, 2011
1:38
Maravilhoso, muito bom inclusive compartilhei no FB.
[]‘s…
Manuel
dezembro 28th, 2011
13:34
muikto manero! me lembrou o papo de botequim do shell script
Mariah
janeiro 31st, 2012
14:45
Muito bom!!!! Adorei o site!!! Parabéns!!!
Ricardo S
fevereiro 16th, 2012
18:50
Parabéns !!! Simples e claro… de fácil compreensão… partilhar conhecimento é a melhor forma de se aprender mais…
Valeu !!!
diego
março 21st, 2012
15:29
Simples e didático, parabéns!
desconhecido
março 27th, 2012
12:30
Saab, MuitoO boOa a explicacao. Objetiva e didatica Vlw
Leave a comment