11 de jan de 2013

Log + Spring + @AspectJ facilitando o trabalho

Neste artigos será apresentada uma solução de log para sistemas que utilizam como controlador de injeção de dependência o Spring.
Inicialmente será passada uma breve explicação sobre orientação à aspectos, logo depois a solução será apresentada.


Orientação a Aspectos

A orientação a aspectos já existe a algum tempo, e desde sua criação uma grande quantidade de material tem sido publicado a seu respeito. Muitos pesquisadores dizem ser a nova bala de prata, outros dizem que não é uma boa solução, outros não concluem nada a respeito. Ainda não há estudo quantitativo relevante que mostre se é uma boa ou não utilizar aspectos. Enquanto isso não se acerta, vamos mostrar uma solução utilizando este paradigma.

O que são aspectos ?

Os aspectos de um programa podem ser ditos como todas as ações comuns que executam em partes diferentes do código, ou seja, os interesses transversais. Alguns exemplos de interesses transversais são log, persistência, filtros, entre outros.Um ponto de execução do programa poderá ser afetado pelo aspecto é chamado de Join Point. O Point Cut é uma expressão escrita na linguagem que implementa o aspecto para selecionar quais join points utilizar.
Quando um join point é atingido a ação (Advice) será executada.
Para implementar a ligação entre aspectos e o objeto alvo utiliza-se o Proxy AOP.


No AspectJ existem 5 tipos diferentes de advice:
  1. Before: ação do advice executa antes do join point.
  2. After returning: ação do advice executa depois do joint ser executado com sucesso, ou seja, sem lançar exceção.
  3. After throwing: ação do advice executa depois do joint ser executado com erro, ou seja, somente quando ele lançar uma exceção.
  4. After (finally): ação do advice executa depois do joint ser executado independente de ter causado ou não exceção.
  5. Around: advice que envolve a execução de um joint point. Com ele é possível codificar ações antes e depois do join point. Inclusive é possível alterar valores passados como parâmetro, como retorno, ou nem mesmo chamar o método do objeto alvo.
Como implementar Orientação a Aspectos ?

O framework Spring disponibiliza uma API que permite trabalhar com diversos aspectos do softwares. Vamos utilizar o Spring 2.5.6, uma versão que já está até um pouco antiga, mas que vai servir apenas de exemplo.

Para baixar as dependências basta adicionar isto ao pom.xml: 

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>2.5.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>2.5.6</version>
        </dependency>

E também a tag <aop:aspectj-autoproxy /> deve ser adicionada ao xml de configuração do Spring.


Implementando log utilizando Aspectos



Umas das principais preocupações ao se desenvolver um sistema é saber quando exceções ocorreram. Para isto, diversas vezes são utilizados inúmeros tratamentos que acabam gerando clones no código. Ou seja, trechos de códigos redundantes que tratam situações semelhantes. Com a utilização do aspecto este tratamento pode ser centralizado em uma parte do código, tornando mais fácil a manutenção. Outra vantagem é que o log pode ser feito padronizado por camadas, pacotes e outras divisões que sejam encontradas no código.

Para implementar basta utilizar os recursos do aspectJ e adicionar a anotação:

@Component

@Aspect 

public class LogManager {



@AfterThrowing(pointcut="execution(*br.pognao.dao)",throwing="ex")

public void trataExcecaoDeDAO ( Exception ex ) {

      metodoTratadorDeExp(ex);

}



@AfterThrowing(pointcut="execution(*br.pognao.controller)",throwing="ex")

public void trataExcecaoDeController ( Exception ex ) {

      metodoTratadorDeExp(ex);

}

}


Desta forma é possível implementar qualquer tratamento de interesses transversais utilizando as anotações mostradas anteriormente.

Mas, é importante ressaltar que aspectos não tem apenas vantagens. Dependendo do interesse tratado, a rastreabilidade do código pode ser prejudicada. Outro ponto importante é caso exista a necessidade de personalizar o trecho de código que utiliza aspectos apenas para uma classe, então o trabalho deverá ser feito novamente na classe que precisa da alteração, caso contrário todo o sistema poderá ser afetado erroneamente.

Refs : http://michelzanini.wordpress.com/ , http://www.springsource.org/ , http://maven.apache.org/ ,











Nenhum comentário:

Postar um comentário