Spring 3, configurando beans com Annotations

Hoje, é muito comum frameworks configuráveis através de annotations. O Spring também possui esse estilo de configuração que é bastante prático e traz produtividade ao desenvolvimento. Você poderá inclusive misturar configuração via XML e Annotations e utilizar qual for mais adequada para cada situação. Nesse tutorial mostraremos como a configuração pode ser feita através de annotations e ainda como pode ser feita a detecção automática dos beans através do classpath scanning.

Esse tutorial é continuação do Hello World com Spring 3 para um projeto WEB, se ainda não tem um projeto Spring configurado, é recomendável ler o outro tutorial antes de prosseguir com esse. Algumas anotações utilizadas nesse capítulo necessitam JEE 5 (como @PostConstruct).

1. Configurando os beans com annotations

Vamos começar configurando beans com Annotations, ao invés de usar a configuração de XML. Como é possível utilizar as duas configurações simultaneamente, a configuração feita através de Annotations é processada antes da configuração via XML. A configuração em XML pode então sobrescrever a configuração feita com Annotations.

Para habilitar a configuração dos beans via annotations, basta adicionar uma tag context:annotation-config no seu arquivo applicationContext.xml (Note a inclusão do namespace context)

<?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>

       <context:annotation-config/>

</beans>

Com essa tag, será possível fazer a configuração dos beans por Annotations.

Vejamos as anotações (alguns dos exemplos mostrados foram retirados da documentação do Spring):

@Required

A anotação @Required é utilizada nos setters das propriedades do bean, veja o exemplo:

public class SimpleMovieLister {

private MovieFinder movieFinder;

    @Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// …
}

Essa anotação indica que essa propriedade deve ser populada na configuração. Caso não haja configuração para essa propriedade uma exceção será lançada pelo container.

@Autowired e @Inject

Como esperado, você pode utilizar a anotação @Autowired em métodos setter. Se estiver utilizando um JAR para o JSR-330 (Injeção de dependencia) poderá utilizar a anotação @Inject. O Spring detecta se o JAR está presente automaticamente. A anotação @Autowired faz a configuração da propriedade de forma automática, buscando na fábrica do Spring algum bean que possa satisfazer a dependencia e então realizando a configuração.

public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// …
}

Propriedade anotadas com @Autowired devem ser obrigatoriamente preenchidas. Você pode alterar esse comportamento através do atributo required, como @Autowired(required=false). A anotação @Inject não tem a mesma definição, sendo o preenchimento opicional.

Também é possível utilizar essa anotação em métodos com nomes aleatórios e com vários argumentos:

public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;

@Autowired
public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// …
}

Você pode usar o @Autowired em construtores e campos:

public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// …
}

@Value

A anotação @Value é utilizada quando temos propriedades que não são outros beans exemplo:

public class MovieCatalog {
@Value(“Comedy”)
String name;

}

@PostConstruct e @PreDestroy

As anotações @PostContruct e @PreDestroy servem para anotar métodos que devem ser chamados quando o container for iniciado e destruido respectivamente. É necessário ter um JAR do JSR-250 para ter disponíveis essas anotações. Se não tiver esse JAR disponível uma alternativa é utilizar os atributos init-method e destroy-method na definição do bean no XML do Spring. Ou o bean implementar as interfaces InitializingBean e DisposeableBean.

2. Contruindo uma aplicação utilizando Annotations

Utilizando uma aplicação que já esteja configurada com o Spring, vamos criar dois beans e utilizar a injeção de dependência através de annotations. Crie duas classes conforme o exemplo:

package org.javaframework.spring;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

public class MostraInformacoesSistema {

    @Autowired
Sistema sistema;

    @PostConstruct
public void mostraInformacoes(){
System.out.println(“Sistema: “+sistema.getNome()+
“, versão: “+sistema.getVersao());
}
}

package org.javaframework.spring;

import org.springframework.beans.factory.annotation.Value;

public class Sistema {

    @Value(“Spring com annotations”)
String nome;

@Value(“1.0”)
String versao;

    public String getNome() {
return nome;
}
public String getVersao() {
return versao;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setVersao(String telefone) {
this.versao = telefone;
}
}

A classe Sistema servirá para guardarmos algumas informações que serão mostradas pela classe MostraInformacoesSistema. Foi utilizada a anotação @Autowired no atributo sistema da classe MostraInformacoesSistema, isso indica para o Spring fazer a configuração dessa propriedade automaticamente. A anotação @PostConstruct fará com que o método mostraInformacoes seja chamado assim que o bean esteja completamente configurado.

Agora vamos configurar o XML do Spring para ler essas anotações e fazer a configuração, configure seu arquivo applicationContext.cml conforme o exemplo:

<?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”>

<context:annotation-config/>

<bean/>

<beanhttp://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-annotation-config” target=”_blank”>3.9 Annotation-based container configuration.

Fizemos a configuração do bean por annotations, mas ainda precisamos declarar o bean no XML. Isso porque a tag context:annotation-config apenas lê as anotações e faz a configuração, mas não implica em detectar as classes automaticamente. Para isso precisamos de outra tag, que será mostrada a seguir.

3. Classpath scanning

Classpath scanning é um recurso do Spring que lê o classpath da aplicação e busca classes que possam ser configuradas, isso evita que você tenha que declarar essas classes no XML. Essas classes são passadas por um filtro e então uma definição de um bean é criada para elas. Geralemente esse filtro é alguma anotação que marca que determinada classe deve ser utilizada como um componente. Essas anotações são: @Component, @Service, @Controller e @Repository (que foi introduzida no Spring 2.0). Você pode também criar suas próprias anotações e filtros para declarar os componentes.

A anotação @Component é um tipo genérico para qualquer bean que deve ser gerenciado pelo Spring. @Repository, @Service e @Controller são especializações de @Component e servem para as camadas de persistencia, serviço e apresentação respectivamente. Você pode utilizar @Component para qualquer classe da sua aplicação, mas utilizar uma anotação mais específica ajuda caso deseje criar um filtro, utilizar ferramentas, ou orientação a aspectos. Funcionalmente todas as anotações servem para declarar beans, não existe diferença entre elas a não ser na questão de organização da apliacação e utilidades citadas anteriormente.

Para detectar as classes e gerar beans precisamos de uma outra tag no applicationContext.xml

<?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”>

<context:component-scan base-package=”org.javaframework”/>

</beans>

Essa tag irá indicar ao Spring para procurar as classes e fazer a configuração dos beans. O atributo base-package indica em qual pacote as classes devem ser lidas, podem ser especificados quantos pacotes desejar, separados por vírgula.

Com essa tag, podemos alterar o applicationContext.xml da aplicação exemplo que criamos, retirando as declarações dos beans. O arquivo applicationContext.xml fica da seguinte forma:

<?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”
>

<context:annotation-config/>
<context:component-scan base-package=”org.javaframework”/>

</beans>

As classes devem ter alguma anotação que indique que são componentes, utilizamos a anotação @Service

package org.javaframework.spring;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class
MostraInformacoesSistema {

    @Autowired
Sistema sistema;

    @PostConstruct
public void mostraInformacoes(){
System.out.println(“Sistema: “+sistema.getNome()
+”, versão: “+sistema.getVersao());
}
}

package org.javaframework.spring;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class Sistema {

    @Value(“Spring com annotations”)
String nome;

@Value(“1.0”)
String versao;

    public String getNome() {
return nome;
}
public String getVersao() {
return versao;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setVersao(String telefone) {
this.versao = telefone;
}
}

Agora, basta criar as classes e utilizar as anotações para fazer a configuração, contando que as classes estejam no pacote definido em base-package elas serão detectadas e configuradas automaticamente, sem a necessidade de intervenção no XML de configuração do Spring.

Mais informações sobre o classpath scanning podem ser obtidas na documentação do Spring, seção 3.10 Classpath Scanning and Managed Components.

Fonte: JavaFramework

Advertisements

About Gustavo Amaro

+ Formado em Tecnologia e Análise de Sistemas + MBA em Desenvolvimento de Aplicações JAVA – SOA

Posted on 1 de Março de 2013, in Java, Spring and tagged , , , , , , , , . Bookmark the permalink. Deixe um comentário.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

%d bloggers like this: