Aspect-Oriented Programming e Middleware

Conceitos

AOP veio para complementar OOP provendo uma nova forma de pensar a respeito da estrutura de um programa.

AOP não veio para substituir OOP, mas sim para melhorar a modularidade de programas de uma forma mais geral, separando melhor algumas preocupações que em geral cortam muitos pontos de um programa.

A seguir algumas definições importantes relacionadas a AOP:

Há três tipos de "advice":

AOP e Design Patterns

É importante destacar que alguns padrões de projeto OO resolvem alguns dos problemas que AOP tenta atacar:

AOP e J2EE

EJB pode ser usado para tratar de forma declarativa algumas preocupações já predefinidas, como gerência de transações.

Pode-se também usar filtros de servlets para execuções antes e depois de requisições HTTP, mas bem vinculadas a API de servlets.

Pode-se usar também um framework como o Web Work 2 que provê a capacidade de interceptação, mas isso é menos geral do que um framework AOP de verdade. Só se vai poder colocar serviços declarativos em certas invocações gerenciadas pelo framework.

EJB como um subconjunto de AOP

EJB é em parte uma forma menos geral de interceptação AOP, usada para acessar um conjunto fixo de serviços J2EE providos por um servidor de aplicação.

Um aspecto em EJB já vai empacotado com o contêiner EJB, que já provê alguns serviços. Um join point em EJB é a execução de um método na interface de um componente EJB. Pointcuts são especificados no EJB deployment descriptor. Eles são descritos estaticamente, em termos de nomes de métodos e opcionalmente na forma de listas de argumentos. O servidor EJB tipicamente faz o weaving dos aspectos, tanto através de geração de código (gerando uma subclasse da classe de implementação do EJB em tempo de deploy e compilando-a) quanto introduzindo um proxy dinâmico ou alguma forma de geração de bytecode.

É importante destacar, porém, que o modelo de interceptação do EJB é mais limitado:

EJB provê um prato feito: Coma tudo o que o chefe preparou, 
quer goste ou não.
AOP oferece uma refeição à la carte: Coma o que quiser, mesmo 
que tenha de ser pedido em outros restaurantes.

Estratégias de Implementação AOP

Dynamic Proxies

São construções de Java 1.3+ que nos permitem criar uma implementação de um ou mais interfaces em tempo de execução. Para implementar um around advice com um dynamic proxy, este deve invocar a corrente de interceptadores necessários. O último invocará um objeto destino (se existir algum) via reflexão.

O Spring usa dynamic proxies quando está lidando com o "proxying" de interfaces. O Nanning usa dynamic proxies exclusivamente.

Vantagens:

Limitações:

Usado por:

Geração Dinâmica de Byte Code

Para fazer o proxy de classes, ao invés de apenas interfaces é necessária a geração dinâmica de byte code. Exemplo de ferramenta para esse fim: CGLIB (Code Generation Library), usada pelo Spring, onde se obtém interceptação via geração de subclasses dinâmicas. A limitação dessa abordagem é que não se vai poder fazer proxy de métodos final.

Geração de Código Java

Abordagem que parece estar caindo em desuso devido aos dynamic proxies e por geração de byte code dinâmico ser mais simples de se trabalhar.

Uso de um Class Loader customizado

Para interceptar todas as instâncias de uma classe particular ou para mudar o construtor de uma classe deve-se investigar o mecanismo de carregamento de classes de Java, onde se pode definir um class loader customizado. Algumas vezes carrega-se informações de arquivos XML de configuração.

Usado por:

Limitação:

Extensões da Linguagem

Obtem-se através de uma linguagem focada em AOP, como AspectJ, que é uma extensão orientada a aspectos de Java.

Implementações AOP

AspectJ

AspectWerks

JBoss 4

Spring

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;


public class DebugInterceptor implements MethodInterceptor{
	public Object invoke (MethodInvocation invocation) throws Throwable {
		System.out.println("Debug interceptor: invocation=["+invocation+"]");
		Object rval = invocation.proceed();

		System.out.println("Debug interceptor: next returned");
		return rval;
  }

}

Nanning

The AOP Alliance

Alguns Desafios de AOP

Perigos oferecidos

Referências