Implementação de Programação Orientada a Aspectos (AOP) via XML no Spring Framework

Embora as anotações sejam amplamente utilizadas no ecossistema Spring moderno, a configuração de Programação Orientada a Aspectos (AOP) via XML continua sendo uma alternatvia robusta, especialmente para centralizar a lógica de infraestrutura sem moidficar o código-fonte das classes de negócio. O funcionamento interno é idêntico ao modelo baseado em anotações, mas a declaração dos join points e advices é feita inteiramente no arquivo de configuração do Spring.

Definição da Classe de Aspecto

Diferente do modelo com anotações, a classe de aspecto em uma configuração XML é um POJO (Plain Old Java Object) comum. Ela não requer nenhuma marcação especial do Spring em seu código-fonte.

package br.com.exemplo.aspecto;

public class MonitoramentoAspecto {

    public void registrarInicio() {
        System.out.println("[AOP] Iniciando execução do método...");
    }

    public void registrarFim() {
        System.out.println("[AOP] Finalizando execução do método (independente do resultado).");
    }

    public void tratarErro(Exception ex) {
        System.out.println("[AOP] Ocorreu uma exceção: " + ex.getMessage());
    }

    public void registrarSucesso(Object resultado) {
        System.out.println("[AOP] Execução concluída com sucesso. Retorno: " + resultado);
    }
}

Configuração do Contexto XML

Para habilitar o suporte a AOP via XML, é obrigatório incluir o namespace aop no cabeçalho do arquivo de configuração. Dentro do elemento <aop:config>, definimos como o aspecto se integra ao fluxo da aplicação.

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- Definição dos beans -->
    <bean id="meuAspecto" class="br.com.exemplo.aspecto.MonitoramentoAspecto" />
    <bean id="servicoUsuario" class="br.com.exemplo.servico.impl.UsuarioServiceImpl" />

    <!-- Configuração AOP -->
    <aop:config>
        <aop:aspect ref="meuAspecto">
            <!-- Definição do Pointcut: intercepta qualquer método em UsuarioServiceImpl -->
            <aop:pointcut id="pontoDeEntrada" 
                expression="execution(* br.com.exemplo.servico.impl.UsuarioServiceImpl.*(..))" />

            <!-- Advices referenciando o pointcut -->
            <aop:before method="registrarInicio" pointcut-ref="pontoDeEntrada" />
            <aop:after method="registrarFim" pointcut-ref="pontoDeEntrada" />
            <aop:after-returning method="registrarSucesso" pointcut-ref="pontoDeEntrada" returning="resultado" />
            <aop:after-throwing method="tratarErro" pointcut-ref="pontoDeEntrada" throwing="ex" />
        </aop:aspect>
    </aop:config>

</beans>

Execução e Teste do Componente

Ao carregar o contexto do Spring, o contêiner criará proxies dinâmicos para os beans que correspondem aos pointcuts definidos. Ao invocar um método do serviço, as ações do aspecto serão disparadas automaticamente de acordo com a configuração XML.

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import br.com.exemplo.servico.UsuarioService;
import br.com.exemplo.modelo.Usuario;

public class AppPrincipal {
    public static void main(String[] args) {
        ApplicationContext contexto = new ClassPathXmlApplicationContext("spring-config.xml");
        UsuarioService service = contexto.getBean(UsuarioService.class);

        Usuario user = new Usuario();
        user.setNome("Dev Senior");
        user.setEmail("senior@tech.com");

        // Esta chamada acionará os interceptores definidos no XML
        service.salvarUsuario(user);
    }
}

A principal vantagem desta abordagem é a separação total entre o código de negócio e a configuração de infraestrutura. Caso seja necessário alterar a estratégia de log ou monitoramento, basta modificar o arquivo XML, sem a necessidade de recompilar as classes de serviço ou o próprio aspecto.

Tags: Spring-Framework AOP java xml-configuration aspect-oriented-programming

Publicado em 9-27 17:15