15 de agosto de 2026 • Java

10 - Aspect Oriented Programming (Spring AOP)

O que é Programação Orientada a Aspectos (AOP)?

A Programação Orientada a Aspectos (AOP) é um paradigma de programação que ajuda a separar as preocupações transversais da lógica de negócio principal de uma aplicação.

Preocupações transversais são funcionalidades que afetam múltiplas partes da aplicação, tais como:

  • Logging (Registro de logs)
  • Segurança
  • Gerenciamento de Transações
  • Monitoramento de Performance
  • Auditoria
  • Tratamento de Exceções

Sem AOP, o mesmo código precisaria ser repetido em várias classes, tornando a aplicação mais difícil de manter.

O Spring AOP permite aos desenvolvedores adicionar essas funcionalidades sem modificar diretamente o código de negócio.


Por que usar AOP?

Sem AOP

@Service
public class PaymentService {

    public void processPayment() {
        System.out.println("Starting method...");

        // Business Logic

        System.out.println("Ending method...");
    }
}

O código de logging está misturado com a lógica de negócio.

Com AOP

@Service
public class PaymentService {

    public void processPayment() {
        // Business Logic
    }
}
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore() {
        System.out.println("Starting method...");
    }
}

A lógica de negócio permanece limpa enquanto o logging é tratado separadamente.


Terminologias em AOP

Entender os principais conceitos de AOP é essencial antes de implementar aspectos.

Aspect

Um Aspect é um módulo que encapsula uma preocupação transversal.

Exemplos:

  • LoggingAspect
  • SecurityAspect
  • MonitoringAspect
  • AuditAspect
@Aspect
@Component
public class LoggingAspect {
}

Join Point

Um Join Point representa um ponto específico durante a execução de um programa onde um aspecto pode ser aplicado.

No Spring AOP, os join points são tipicamente:

  • Execução de método
  • Execução de construtor (suporte limitado)
  • Tratamento de exceções

Exemplo:

paymentService.processPayment();

A execução de processPayment() é um join point.


Advice

Um Advice define qual ação deve ser executada e quando.

Spring oferece vários tipos de advice:

AdviceDescrição
@BeforeExecuta antes de um método
@AfterExecuta depois de um método
@AfterReturningExecuta após uma execução bem-sucedida
@AfterThrowingExecuta quando ocorre uma exceção
@AroundExecuta antes e depois de um método

Exemplo

@Before("execution(* com.example.service.*.*(..))")
public void logBefore() {
    System.out.println("Method execution started");
}

Pointcut

Um Pointcut define onde um advice deve ser aplicado.

Exemplo:

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}

Este pointcut seleciona todos os métodos dentro do pacote de serviço.


Target Object

O Target Object (Objeto Alvo) é o objeto cuja execução de método está sendo interceptada.

Exemplo:

@Service
public class PaymentService {
}

PaymentService é o objeto alvo.


Weaving

Weaving (Tecer) é o processo de conectar aspectos a objetos alvo para criar um objeto aconselhado (advised object).

Spring realiza o weaving em tempo de execução usando proxies.


Proxies AOP

O que é um Proxy?

Um proxy é um objeto criado pelo Spring que fica entre o cliente e o objeto alvo.

Em vez de chamar o alvo diretamente:

Cliente → PaymentService

A chamada passa por um proxy:

Cliente → Proxy → PaymentService

O proxy executa quaisquer aspectos configurados antes e/ou depois de chamar o método alvo.


Por que os Proxies são Necessários?

Spring AOP é baseado em proxy.

O proxy é responsável por:

  • Interceptar chamadas de método
  • Aplicar advice
  • Invocar o método alvo
  • Retornar resultados

Sem proxies, o Spring não seria capaz de injetar comportamento transversal dinamicamente.


Tipos de Proxies no Spring

JDK Dynamic Proxy

Usado quando a classe alvo implementa uma interface.

public interface PaymentService {
    void processPayment();
}
@Service
public class PaymentServiceImpl implements PaymentService {
}

Spring cria um proxy baseado na interface.


CGLIB Proxy

Usado quando nenhuma interface existe.

@Service
public class PaymentService {

    public void processPayment() {
    }
}

Spring gera uma subclasse dinamicamente em tempo de execução.


Regras de Seleção de Proxy

CenárioTipo de Proxy
Classe implementa interfaceJDK Dynamic Proxy
Classe sem interfaceCGLIB
force proxyTargetClass=trueCGLIB

Exemplo:

@EnableAspectJAutoProxy(proxyTargetClass = true)

Limitação dos Proxies do Spring

Spring AOP só intercepta chamadas de método que passam pelo proxy.

Exemplo:

@Service
public class UserService {

    public void methodA() {
        methodB();
    }

    public void methodB() {
        System.out.println("Method B");
    }
}

Se um aspecto for aplicado a methodB(), ele não será acionado quando methodA() o chamar internamente porque a chamada não passa pelo proxy.

Isso é conhecido como o Problema de Auto-Invocação.


Expressões de Pointcut

O que é uma Expressão de Pointcut?

Uma Expressão de Pointcut é uma regra usada para selecionar quais métodos devem receber um advice.

Spring usa a sintaxe de expressão do AspectJ.


Sintaxe Básica

execution(modifiers-pattern?
          return-type-pattern
          declaring-type-pattern?
          method-name-pattern
          parameter-pattern
          throws-pattern?)

Exemplo:

execution(* com.example.service.*.*(..))

Wildcards

Corresponder a Qualquer Tipo de Retorno

execution(* com.example.service.*.*(..))

* significa qualquer tipo de retorno.


Corresponder a Qualquer Nome de Método

execution(* com.example.service.*.*(..))

Corresponde a todos os métodos.


Corresponder a Quaisquer Parâmetros

execution(* com.example.service.*.*(..))

(..) significa zero ou mais parâmetros.


Expressões de Pointcut Comuns

Todos os Métodos em um Pacote

execution(* com.example.service.*.*(..))

Todos os Métodos em Subpacotes

execution(* com.example.service..*.*(..))

Os dois pontos (..) incluem subpacotes.


Método Específico

execution(* com.example.service.UserService.findUser(..))

Métodos Começando com “find”

execution(* com.example.service.*.find*(..))

Exemplos:

findUser()
findById()
findAll()

Métodos com Tipo de Retorno Específico

execution(List com.example.service.*.*(..))

Corresponde apenas a métodos que retornam List.


Métodos com Um Parâmetro String

execution(* *(String))

Métodos com Qualquer Número de Parâmetros

execution(* *(..))

Usando Pointcuts Nomeados

Em vez de repetir expressões:

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}

Reutilize-as:

@Before("serviceLayer()")
public void logBefore() {
}

Isso melhora a legibilidade e a manutenibilidade.


Exemplo Completo

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethods() {}

    @Before("serviceMethods()")
    public void beforeMethod() {
        System.out.println("Method started");
    }

    @AfterReturning("serviceMethods()")
    public void afterMethod() {
        System.out.println("Method finished");
    }
}

Vantagens do Spring AOP

  • Separa as preocupações transversais da lógica de negócio.
  • Melhora a legibilidade do código.
  • Reduz a duplicação de código.
  • Manutenção mais fácil.
  • Centraliza logging, segurança, auditoria e monitoramento.
  • Integra-se perfeitamente com o Spring Framework.

Desvantagens do Spring AOP

  • Pode tornar o fluxo da aplicação mais difícil de seguir.
  • A depuração pode se tornar mais complexa.
  • Limitação de auto-invocação devido à implementação baseada em proxy.
  • A criação de proxy em tempo de execução introduz uma pequena sobrecarga.
  • Suporta apenas join points de execução de método (ao contrário do AspectJ completo).

Resumo

Spring AOP é um recurso poderoso que permite aos desenvolvedores modularizar preocupações transversais como logging, segurança, monitoramento e gerenciamento de transações. Ele funciona através de proxies gerados em tempo de execução que interceptam chamadas de método e aplicam advice com base em expressões de pointcut. Compreender os conceitos centrais — Aspect, Advice, Join Point, Pointcut, Proxy e Weaving — é essencial para usar efetivamente o AOP em aplicações Spring.

← Voltar para o blog