Spring Framework

As anotações são funcionalidades introduzidas no Spring a partir da versão 2.5, possibilitando aos desenvolvedores um aumento significativo em produtividade. Isto se deve à facilidade de configuração via anotações, o que era mais complicado nas versões anteriores do Spring, pois toda configuração era via XML. Mas nem só de anotações vive o Spring. Existem muitos conceitos importantes que devem ser bem compreendidos. Dois dos principais são a Injeção de Dependência e Inversão de Controle. Existem muitos artigos bons que explicam estes conceitos, principalmente o de Martin Fowler, e outros aqui mesmo na DevMedia, portanto, nos restringiremos a explicações superficiais e práticas destes conceitos.

A Inversão de Controle, basicamente, é uma forma diferente de manipularmos o controle sobre um objeto. Não somos nós que iremos gerenciar a criação de instância dos objetos (no popular, dar o famoso "new"). Quem se encarregará de fazer isso, no nosso caso, é o próprio Spring. E a injeção de dependências? Bom, como não vamos criar um novo objeto, então precisaremos que alguém nos dê esse objeto, ou mais precisamente, nos dê essa dependência. Além disso, precisaremos que este alguém (o Spring) injete essa dependência em nossa classe. Confuso? Vamos ver como é simples, a partir de um exemplo. A Listagem 1 mostra a primeira versão da nossa classe RelacionamentoComCliente.

Listagem 1: Primeira tentativa da criação da Classe RelacionamentoComCliente


public class RelacionamentoComCliente{

NewsLetter news = new NewsLetter();

Cliente cliente = new Cliente();
Cliente cliente1 = new Cliente();
//Cliente n .....
 
public void enviarNewsletter() {

cliente.setNome("Leonel Messi");
 cliente.setCpf("999.999.999-99");

news.adicionarPromocao("Promoção de cerveja !! Aproveite");

news.enviarPromocaoParaCliente(news,cliente);

cliente1.setNome("Neymar dos Santos");
 cliente1.setCpf("999.999.999-99");
news.enviarPromocaoParaCliente("Promoção de cerveja !! Aproveite", cliente1);
 // Cliente n.set....... e vai

}
}

A classe RelacionamentoComCliente apresenta duas dependências, a NewsLetter e a Cliente. O problema é que não é responsabilidade da classe RelacionamentoComCliente criar e manipular esses objetos, isso contribui para diminuir a coesão entre as classes, além de outros problemas. No exemplo, imagine se tivéssemos que mudar a promoção, e ela estivesse sendo usada por diversas classes do sistema. Teríamos que refatorar muitas partes da aplicação. Agora veja a classe RelacionamentoComCliente, usando um mecanismos de IOC, ou seja, Inversão de Controle.

Listagem 2: Segunda tentativa da criação da Classe RelacionamentoComCliente


public class RelacionamentoComCliente{

NewsLetter news;
Cliente cliente;
 
public void enviarNewsletter(News news, Cliente cliente) {

	news.enviarPromocaoParaCliente(news,cliente);

}
 	
}

Os mecanismos do Spring para implementar estes conceitos de injeção de dependência e inversão de controle, necessitam de algumas anotações, conforme mencionado no inicio do artigo. As anotações que veremos neste artigo estão baseadas na versão 3.1 do Spring. A Tabela 1 mostra essas anotações:

@Component Anotação genérica para qualquer componente gerenciado pelo Spring. Esta anotação faz com que o bean registrado no Spring possa ser utilizado em qualquer bean, seja ele um serviço, um DAO, um controller, etc. No nosso exemplo, ele será responsável por um Bean que representa uma entidade.
@Repository Anotação que serve para definir uma classe como pertencente à camada de persistência.
@Service Anotação que serve para definir uma classe como pertencente à camada de Serviço da aplicação.
@Autowired A anotação @ Autowired fornece controle sobre onde e como a ligação entre os beans deve ser realizada. Pode ser usado para em métodos setter, no construtor, em uma propriedade ou métodos com nomes arbitrários e / ou vários argumentos.

Tabela 1: Anotações do Spring usadas na aplicação

Bom, agora é começar o projeto. Para isso, abra o IDE Eclipse e crie um novo Java Project. Após isso, crie um arquivo XML simples, e o nomeie de spring-autoscan.xml, conforme pode ser visto na Listagem 3. Este arquivo será o responsável pela configuração do Spring Framework. Após isso, vamos criar uma classe Java, nomeando-a para App.java. Esta classe é a principal de nossa aplicação, e é responsável por colocar o Spring dentro do contexto da aplicação, ou seja, permite que o Spring trabalhe por nós. Pedimos então ao Spring que inicie sua execução a partir do método save(), presente na classe ClienteService, conforme pode ser visto na Listagem 4.

Listagem 3: Arquivo de configuração do Spring Framework


<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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 
    <context:component-scan base-package="br.com" />
 
</beans>

Listagem 4: Classe que insere o Spring no contexto da aplicação (App.java)


package br.com.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import br.com.cliente.service.ClienteService;

public class App {
    public static void main( String[] args ) {
    	ApplicationContext context = new 
                           ClassPathXmlApplicationContext(new String[]
                                     {"spring-autoscan.xml"});
     	ClienteService cliente = (ClienteService)context.getBean
                                 ("clienteService");
    	cliente.save();
     }
}

A classe ClienteService tem duas dependências gerenciadas e injetadas pelo Spring. São elas a classe Cliente, apresentada na Listagem 6 e a classe ClienteDao, mostrada na Listagem 7. A classe ClienteService apresenta algumas anotações. A anotação @Service representa esta classe como se fosse um serviço. Já as anotações @Autowired permitem que o Spring injete as dependências nesta classe, conforme pode ser visto na Listagem 5.

Listagem 5: Classe ClienteService.java


package br.com.cliente.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import br.com.cliente.dao.ClienteDao;
import br.com.cliente.entity.Cliente;

@Service
public class ClienteService {

	@Autowired
	ClienteDao clienteDAO;
	@Autowired
	Cliente cliente;
 
	public void save() {
		cliente.setNome("Leonel Messi");
		System.out.println("Cliente foi manipulado no Service");
		clienteDAO.save(cliente);
 	}
}

Listagem 6: Classe Cliente.java


package br.com.cliente.entity;

import org.springframework.stereotype.Component;

@Component
public class Cliente {

	private String nome;
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
}

Listagem 7: Classe ClienteDao.java


package br.com.cliente.dao;

import org.springframework.stereotype.Repository;
import br.com.cliente.entity.Cliente;
	 
@Repository
public class ClienteDao 
{
	public void save(Cliente cliente) {
		System.out.println("Cliente salvo no Dao: "+cliente.getNome());
		
	}	
}

Bom pessoal, apesar de ser um artigo introdutório, vimos duas das principais características, a Injeção de Dependências e a Inversão de Controle, que tornaram o Spring um dos frameworks mais utilizados. Obrigado, e até um próximo artigo, abraço.