Entendendo os stereotypes do Spring
Conheça o conceito de estereótipos do Spring e aprenda como criar o seu próprio estereótipo
A base de todo o funcionamento do Spring consiste no conceito de metaprogramação, que pode ser declarado através de XML ou anotações. Desde o Spring 3.0 a tendência passou a ser a eliminação de configuração da aplicação via XML e a adoção de configuração programática via código Java e via anotações. Uma parcela desta tendência é a possibilidade de criar objetos complexos através da anotação @Bean
.
Hoje em dia é possível configurar toda sua aplicação com Spring utilizando apenas código Java e anotações. Por exemplo, para declararmos uma classe como gerenciada pelo container de IoC/DI do Spring, basta anotá-la com @Component. Dessa forma, ela já será instanciada, registrada no container e estará pronta para o uso dentro da aplicação.
No entanto, ter todas as classes do sistema anotadas com @Component
é muito genérico, pois estamos apenas dizendo que tais classes são componentes (beans) gerenciados pelo Spring. Um desenvolvedor olhando para o código teria que se basear pelo nome da classe ou pacote para distinguir se a classe se trata de um DAO, serviço ou um managed bean.
Pensando nisso e levando em conta que a arquitetura da maioria das aplicações Java são divididas em camadas, o Spring resolveu adicionar algumas anotações que possuem um significado mais claro para o desenvolvedor e para as principais camadas de uma aplicação. Este conceito de ter anotações com uma semântica melhor definida é chamado de Stereotypes.
Além da anotação @Component
, o Spring nos fornece mais 3 (três) anotações, @Contoller, @Service e @Repository. Cada uma delas denota uma responsabilidade dentro das camadas da aplicação, como podemos ver abaixo:
@Contoller
- Utilizada para a camada de apresentação. Normalmente anotamos classes que representam a interação do usuário, como managed beans, actions e controllers;@Service
- Utilizada para a camada de aplicação e negócio. Comumente usada para anotar classes que denotam serviços de aplicação e de regras de negócio;@Repository
- Utilizada para a camada de persistência. Normalmente anotamos classes que representam um DAO, Repositório etc;@Component
- Utilizada para classes que não se encaixam em nenhuma das anotações acima. É comum anotar classes utils, parsers, helpers, processadores de arquivo etc;
É importante salientar que @Component
é a anotação mais genérica do Spring e que as outras 3 anotações são especializações dela, isto é, elas herdam de @Component
. Portanto, no geral a prática de anotar uma classe com qualquer uma das anotações não faz diferença para o Spring, mas semanticamente importa para a arquitetura da aplicação e principalmente para o desenvolvedor.
Criando seu próprio stereotype
Embora o Spring nos forneça um bom conjunto de anotações com suas determinadas semânticas, existem situações dentro da aplicação na qual se torna quase impossível evitar a duplicação de código, ou melhor, de metaprogramação. Por exemplo, é muito comum configurarmos os serviços da aplicação para delimitar o controle transacional de nossas regras de negócios, como a seguir:
@Service
@Scope(value = "prototype")
@Transactional(readOnly = true, rollbackFor = ErroDeNegocioException.class)
public class ProdutoService {
}
As três anotações acima estão configurando a classe ProdutoService
como um bean de serviço com o escopo prototype, com todos seus métodos com transação somente-leitura por padrão e efetuando rollback caso a exceção ErroDeNegocioException
seja lançada por algum de seus métodos. Com o passar do tempo e a evolução da aplicação não é difícil encontrar outras classes com a mesma configuração:
@Service
@Scope(value = "prototype")
@Transactional(readOnly = true, rollbackFor = ErroDeNegocioException.class)
public class NotaFiscalService {
}
Se no futuro precisarmos modificar a estratégia de transações padrão ou mesmo o escopo do bean nós teremos que modificar todas as classes da aplicação, o que pode levar a erros por parte do desenvolvedor. Para resolver este problema, nós podemos estender os estereótipos padrões do Spring e criar os nossos próprios, como abaixo:
@Service
@Scope(value = "prototype")
@Transactional(readOnly = true, rollbackFor = ErroDeNegocioException.class)
public @interface ReadOnlyService {
}
E agora podemos simplesmente anotar nossas classes com este novo estereótipo:
@ReadOnlyService
public class NotaFiscalService {
}
O mais interessante é que não precisamos fazer qualquer configuração na aplicação, o Spring irá automaticamente detectar todos as classes anotados como beans gerenciáveis e tudo funcionará normalmente.
Embora o conceito de stereotypes e a possibilidade de criar anotações customizadas tenham sido introduzidas desde a versão 3.0 do Spring, eles são apenas uma pequena parte do poder do framework. Com um pouco de criatividade e atenção é possível evitar duplicação de código, inserir semântica nas anotações utilizadas por sua aplicação, melhorar a comunicação do seu time e até facilitar regras para pointcuts ao trabalhar com Spring AOP, como é o caso da anotação @Repository
que já possui uma tradução de exceções automática.
Não podemos esquecer que as anotações padrões do Spring podem receber semânticas adicionais em futuras versões, por isso, sempre que pensar em anotar alguma classe com @Component
, reflita se ela não seria melhor definida como um serviço, DAO ou mesmo um controller. Os estereótipos e as principais anotações do Spring são estudadas no nosso curso de JSF 2 com Spring.
E você, o que tem feito para evitar duplicação de anotações nas suas classes? Já conhecia o conceito de estereótipos o Spring?
Desenvolvedor e instrutor na TriadWorks
Posted in: diiocjavaspringstereotypes