logo
  • Home
  • Acerca
  • Autores
  • Faq
  • Rede
  Twitter   Feed-me! RSS!

Injeção de dependência com Spring

Colocado por DClick Team na(s) categoria(s): 1, 2.0, 4, 6, app, AR, auto, back, Banco de Dados, BI, busca, class, classe, classes, codec, código, comunidade, control, dados, Desenvolvimento, Dica, Documentação, Download, exemplo, for, framework, Frameworks, futuro, Google, IE, if, int, Java, JPA, lógica, NaN, O, on, padrão, print, problema, programação, referencia, RIA, Ria’s Geral, serviço, singleton, site, Spring, SpringFramework, string, Sun, tag, TAT, Tema, Teste, Tutorial, Twitter, UI, uint, utils, web, XML em 09 17th, 2010 | Sem comentários

Twitter!


Começando com o Spring

Este post visa ajudar na compreensão de um dos conceitos mais difundidos de OO e que ajudaram a tornar o Spring um dos frameworks mais utilizados na comunidade: Inversão de Controle. Um dos casos de Inversão de Controle é a Injeção de Dependências, e é dela que trataremos neste post.

Inversão de Controle e Injeção de Dependência

Imagine que queremos implementar um serviço web que disponibiliza algumas informações do sistema, recuperando algumas informações do banco de dados e executa algumas regras de negócio sobre elas. Para isso nosso serviço deveria de alguma maneira acessar o banco de dados da aplicação, por exemplo através de um ‘DAO‘, e a partir do DAO recuperar os dados necessários. Com os dados em mãos nosso serviço consegue delegar para alguma classe do sistema executar as regras de negócio que se apliquem, por exemplo um ‘Manager‘.

Para este exemplo o mais direto seria instanciar em nosso serviço um objeto da classe DAO e um objeto da classe Manager para que possam ser usados. Em teoria isso seria uma tarefa simples, porém no nosso dia-a-dia de desenvolvimento sabemos que configurar um DAO que acessa o banco de dados não é tão simples assim. Além do DAO, nosso serviço precisa instanciar também uma ‘SessionFactory‘, configurar uma conexão com o banco e outras coisas dependendo da implementação da JPA que se está utilizando. O mesmo vale para a classe de negócio, pois tal classe pode precisar de outras classes mais especializadas e sendo assim, todas essas classes também devem ser intanciadas em nosso serviço.

A situação fica pior se quisermos criar um novo serviço que por exemplo usu o mesmo DAO, mas use classes de negócio diferente. Toda a lógica de instanciar o DAO deve ser replicada no novo serviço.

Agora imagine que temos o mesmo problema para ser resolvido, implementar um serviço web, porém ao invés de nos preocupar em instanciar as classes que iremos precisar, elas já estivessem instanciadas e configuradas corretamente e inclusive ‘setadas‘ em nosso serviço prontas para uso. Esse padrão de deixar a responsabilidade de criar e configurar classes que estarão disponíveis na aplicação fora das classes que as usam se chama Inversão de Controle. Estamos tirando a lógica de criação de dependências das classes chamadas, e deixando a cargo das classes que chamam. Quando temos as dependências criadas e configuradas, e temos as classes que irão usá-las e ‘injetamos‘ as denpendências nas mesmas, temos o que chamamos de Injeção de Dependências.

No Spring o responsável por criar e configurar as classes que serão usadas é chamado de ‘BeanFactory‘, e tais classes são chamadas de ‘beans‘. ‘Beans’ do Spring estão disponíveis no ‘container‘ e podem ser recuperados a qualquer momento dentro do contexto da aplicação. No Spring o contexto da aplicação é representado pelo ‘ApplicationContext‘ que pode ser criado de várias maneiras. Iremos abordar isso mais pra frente.

Definindo um ApplicationContext

Tudo no Spring começa a partir de um contexto da aplicação. Por isso precisamos criar um antes de utilizarmos os princípios de inversão de controle e injeção de dependência. Dentro das maneiras de criar um ApplicationContext usaremos a criação por XML, que é simples o suficiente para começarmos a usar o Spring. Para isso defina o seguinte arquivo XML no seu projeto com o nome de ‘applicationContext.xml‘:

1
2
3
4
5
6
7
8
9
<?xml version=“1.0″ encoding=“UTF-8″?>
<beans xmlns=“http://www.springframework.org/schema/beans”
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xmlns:context=“http://www.springframework.org/schema/context”
    xsi:schemaLocation=“http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd”
>

</beans>

Lembre que para utilizar o framework, você precisa ter os jars do Spring referenciados no seu projeto. Estamos usando a versão 3, que podem ser encontrados no próprio site do Spring (http://www.springsource.org/download). A princípio só usaremos os módulos ‘spring-beans‘ e ‘spring-context‘.

Dica: se o seu projeto está usando o maven, você pode apenas adicionar as seguintes dependências que o maven se encareguará de referenciá-las no seu projeto:

1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>3.0.2.RELEASE</version>
</dependency>

Crie uma classe para executarmos alguns testes, como por exemplo a classe abaixo com um método ‘main‘:

1
2
3
4
5
6
7
8
package br.com.dclick;

public class ClasseMain {

    public void main(String… args) {
       
    }
}

Dentro do nosso método ‘main’, iremos criar um novo ApplicationContext a partir do XML que definimos acima:

1
2
ApplicationContext applicationContext =
                         new ClassPathXmlApplicationContext(“applicationContext.xml”);

Definindo nossos primeiros Beans

Iremos definir agora os beans que estarão disponíveis em nossa aplicação. Existem duas maneiras de se fazer isso. A primeira e que era usada até a versão 2.0 do Spring é através de XML. Para isso basta definir os beans dentro do nosso aaplicationContext.xml. Veremos exemplo em breve. Uma segunda maneira que foi introduzida a partir da versão 2.5 do Spring, é através de anotações. Para usarmos anotações precisamos colocar uma linha a mais no applicationContext.xml:

1
<context:component-scan base-package=“br.com.dclick” />

No atributo ‘base-package‘ você deve colocar o caminho do pacote onde ficarão as classes dos seus beans.

Precisamos agora de classes para serem nossos beans. Vamos criar uma classe qualquer apenas para entender a injeção de dependências:

1
2
3
4
5
6
7
8
9
package br.com.dclick;

public class MockTestClass {

    private String a;

    public String getA() {return a;}
    public void setA(String a) {this.a = a;}
}

E uma outra classe que dependa de MockTestClass:

1
2
3
4
5
6
7
8
9
10
package br.com.dclick;

public class MockTestClass2 {

    private MockTestClass mockBean;

    public MockTestClass getMockBean() {return mockBean;}

    public void setMockBean(MockTestClass mockBean) {this.mockBean = mockBean;}
}

Repare que as classes possuem atributos privados e seus respectivos ‘getters‘ e ‘setters‘. O Spring consegue injetar dependências diretamente nos atributos, mas para começar iremos usar o padrão de ‘getter‘ e ‘setter‘.

Vamos disponibilizar os beans de nossas duas classes em nosso ApplicationContext. Se você preferir usar XML, basta adicionar o seguinte dentro da tag ‘beans‘ do applicationContext.xml:

1
2
3
4
5
<bean class=“br.com.dclick.MockTestClass” id=“mockBean”>
</bean>

<bean class=“br.com.dclick.MockTestClass2″ id=“mockBean2″>
</bean>

Repare que a tag ‘bean‘ recebe dois parâmetros: ‘class‘ e ‘id‘. A tag ‘class‘ indica o caminho o absoluto do no bean, nesse caso temos o MockTesClass e MockTestClass2 como nossos beans. A tag ‘id‘ define um nome para os nossos beans, no caso ‘mockBean‘ e mockBean2‘. Usaremos esse nome para recuperá-los do container.

Caso você deseje usar anotações, basta adicionar o seguinte nas classes dos beans (não esqueça de adicionar a linha no applicationContext.xml que indica o pacote com os beans):

1
2
@Component(“mockBeans”)
public class MockTestClass {

E para MockTestClass2:

1
2
@Component(value = “mockBean2″)
public class MockTestClass2 {

Agora temos nossos dois beans disponíveis no container da aplicação. Para validar que tudo está criado corretamente, volte em nossa classe com método ‘main’ e adicione o seguinte código:

1
2
MockTestClass mockBean = (MockTestClass) applicationContext.getBean(“mockBean”);
System.out.println(“Mock Bean: “ + mockBean);

Rode o código e repare que foi impresso no console o endereço do seu bean. Faça o mesmo para o segundo bean:

1
2
MockTestClass2 mockBean2 = (MockTestClass2) applicationContext.getBean(“mockBean2″);
System.out.println(“Mock Bean 2: “ + mockBean2);

Adicione o seguinte código no final do método:

1
System.out.println(“Mock Bean de Mock Bean 2: “ + mockBean2.getMockBean());

Rode e perceba que mockBean está nulo. Isso porque não falamos para o Spring que ele deveria injetar essa dependência em nosso bean de maneira automática. Existem algumas formas de se configurar esse comportamento. Seguindo nosso padrão até agora, vamos injetar a dependência pelo XML e via anotações, em um post futuro trataremos de injeção automática de dependências.

No XML modifique o ‘mockBean2‘ adicionando o seguinte trecho:

1
2
3
4
5
<bean class=“br.com.dclick.framework.utils.test.mock.MockTestClass2″>
    <property name=“mockBean”>
        <ref bean=“mockBean”/>
    </property>
</bean>

Na tag ‘property‘ definimos uma propriedade do bean que deve ser gerenciada pelo Spring, nesse caso a propriedade é o ‘mockBean‘. Com isso o Spring irá invocar o ‘setMockBean‘ e injetar a dependência. Já com anotações basta anotar o ‘setter‘ de ‘mockBean‘ com ‘@Autowired‘. Dessa forma o Spring irá buscar por um bean com nome ‘mockBean’ no container e caso encontre este será injetado automaticamente:

1
2
@Autowired
public void setMockBean(MockTestClass mockBean) {this.mockBean = mockBean;}

O resultado de ambas as maneiras é exatamente o mesmo. Para ter certeza, rode novamente nossa classe de teste, e repare no endereço impresso no console. Note que o endereço do ‘mockBean‘ é o mesmo tanto quando recuperamos direto do ApplicationContext, quanto do ‘mockBean2‘. Isso acontece porque por padrão, todo bean do Spring é ‘Singleton‘ dentro do contexto da aplicação. Iremos tratar de escopo de beans em um post futuro, mas se você deseja testar basta adicionar o seguinte para que seu bean seja criado sempre que requisitado:

No XML adicione ‘scope=”prototype”‘:

1
2
<bean class=“br.com.dclick.MockTestClass” id=“mockBean” scope=“prototype”>
</bean>

Via anotação adicione ‘@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)‘ na classe:

1
2
3
@Component
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class MockTestClass {

Rode a classe e repare que os endereções agora são diferentes.

Cobrimos o básico de injeção de dependência do Spring. Existem muitas outras maneiras de se injetar dependências nos beans, de se gerenciar criação de beans, de declarar beans enfim, vimos pouca coisa mas que já suficiente para começarmos a estudar alguns conceitos um pouco mais avançados de OO e entendermos melhor o funcionamente de alguns frameworks. A documentação do Spring é uma das melhores disponíveis na comunidade, por isso recomendo a consulta (http://www.springsource.org/documentation). Vamos nos aprofundar mais no funcionamento e diferentes usos do Spring em posts futuros.



Veja o post original no blog do autor aqui!  

DClick Team

Escrito por DClick Team @ http://blog.dclick.com.br/pt/
Saiba mais sobre o autor na sua pagina de perfil
Outros posts do autor:
» Apresentação Spring Framework
» Usabilidade Mobile – Uma visão de Jakob Nielsen
» O Segredo das 1600 Views

Deixe um comentário



Spam Protection by WP-SpamFree

ACERCA

O que é o RedeRIA ?

O redeRIA não é nada mais que um agregador de feed's que disponibiliza o conteudo de varios blogs e autores ao redor do mundo RIA, actualmente agregamos mais de 2791 entradas vindas de 53 blogs especializados em ria’s, pelo que só fica a ganhar em assinar o feed ou seguir a comunidade no twitter.

Se acha que o seu blog ou um blog de um amigo é interessante e util para os leitores o redeRIA, faça a sua submissão aqui.

Feed: assine já
Twitter: siga-nos

GOOGLE

Votação


Deveria o RedeRia agregar conteúdo em inglês?
Ver Resultados

AUTORES


Eduardo KrausAlexandre TadashiBindableCognitiva SoluçõesDaniel LopesDaniel SchmitzDanielPedrinhaDClick TeamEbercomEdgard DavidsonElvis FernandesErko BrideeFabiel PrestesFábio Batista da SilvaFabio da SilvaFabriccio BernardesFelipe BorellaFlavia MoreiraGabriel VersalliniGabriela T. PerryIgor MusardoJanderson CardosoJoão AugustoJose Carlos FielKelps SousaLeonardo FrançaLucas MarçalLuis MessiasLuiz TarabalMario JuniorMário SantosMauro MartinsPablo SouzaPedro ClaudioreneRia BrazilriaPTRicardo CerqueiraRobson FernandesRodrigo Pereira FragaSaintBrSamuelFacchinelloSergio SouzaSilva DeveloperStefan HorochovecTech CaffeTecinforThiago BuenoVedVinícius SandimWillian ManoXAML Cast

PUBLICIDADE








Powered by Wordpress & msdevstudio.com