Post on 11-Jun-2015
Introdução a AOP + SpringAOP
Jobson Ronan {jrjs@cin.ufpe.br}
Motivação
Atualmente OOP é o paradigma de desenvolvimento de software mais adequado
Por que? Emcapsulamento Herança Polimorfismo
Porém, OOP não trata adequadamente de comportamentos que aparecem sobre muitos módulos
Um sistema como um conjunto de interesses
Um complexo sistema de software pode ser visto como uma implementação combinada de múltiplos interesses Lógica de negócios Performance Persistência Logging Debugging Autenticação Segurança Etc.
Um sistema como um conjunto de interesses
Dado um conjunto de requisitos, pode-se identificar uma série de interesses
Interesses atravessadores
Sistemas são criados em resposta a requisitos Core module-level requirements System-level requirements
Muitos requisitos do sistema tendem a ser ortogonais (mutuamente dependentes) de outros e de requisitos de módulos.
Requisitos do Sistema tendem a atravessar muitos modulos
Interesses atravessadores
Exemplo//...public class AccountService {
public void updateAccount(updateAccount acount) throws Exception { SecurityManager.requireUserRole(“admin”);
TransactionManager.beginTransaction(); try { //...código de negócio TransactionManager.commit(); log.info(“acount updated”); } catch (Exception e) { TransactionManager.rollback(); log.warning(“exception throw”, e); throw e; }}
///...
Segurança
Transações
Logging
Problemas
O espaço de requisitos é multidimensional, enquanto o de implementação é unidimensional
Sintomas Código misturado Código espalhado
Afeta o desenvolvimento do software
Problemas
Pobre delineabilidade Diminuição da produtividade Menor reuso de código Baixa qualidade de código Evolução mais dificultada
Soluções
Mix-in Classes Design Patterns
Visitor e Tamplate Method Específico de domínio
EJBs
Separação de Interesses e AOP
AOP permite implementar individuais interesses de maneira fracamente acoplada e combinar essas implementações no sistema final. Permite uma implementação modularizada de interesses
atravessadores (crosscuting concerns) Essa unidade de modularização é chamada de Aspecto
Estágios de desenvolvimento Decomposição aspectual Implementação do interesse Recomposição aspectual
Estágios de desenvolvimento
Benefícios
Implementação modularizada de interesses atravessadores
Sistemas fáceis de evoluir Decisões de modelagem atrasadas Maior reuso do código
SpringAOP
Uma das chaves do Spring e seu framework de AOP Apesar do container IoC do Spring não depender de
AOP, este completa o Spring oferecendo soluções interessantes Disponibilizar serviços declarativos coorporativos, como
gerenciamento de transações e autenticação Possibilitar a implementação de aspectos customizados
Conceitos
Aspecto: Implementado no Spring como Advisors ou Interceptors
Joinpoint: Ponto de execução de um programa. No SpringAOP é sempre referente a
uma invocação de método Advice:
Ação tomada pelo framework AOP em algum Joinpoint Pointcut:
Um conjunto de Joinpoints para os quais um advice deve ser disparado Objeto Alvo:
Objeto contendo joinpoints. Também chamado de advised ou proxied
Conceitos
Introduction: Adicionar métodos e atributos em uma classe advised. Spring
permite introduzir novas interfaces para objetos advised. Proxy AOP:
Um objeto criado pelo framework de AOP, contendo um advice. Weaving:
Aplicação de aspectos para criar objetos advised.
Tipos de Advices
Around advice Before advice Throws advice After Returning advice
Tipos de Weaver
Estático Aspectos são tipicamente introduzidos ao byte code em tempo
de compilação ou através de classloaders customizados em tempo de execução AspectJ (byte code) JBoss AOP, AspectWerkz (classloader)
Dinâmico Cria proxies para todos os objetos interessados Leve perda de performance Fácil de configurar Spring
Em prática
public interface IBusinessLogic { public void foo();}
public class BusinessLogic implements IBusinessLogic { public void foo() { System.out.println( “Inside BusinessLogic.foo()” ); }}
Em prática
import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApplication { public static void main(String [] args) { // Read the configuration file ApplicationContext ctx = new FileSystemXmlApplicationContext("springconfig.xml"); //Instantiate an object IBusinessLogic testObject = (IBusinessLogic)
ctx.getBean("businesslogicbean"); // Execute the public // method of the bean testObject.foo(); }}
Entendendo
Uma vez que nossa MainApplication chama o método ctx.getBean() ela abre mão da instanciação e gerênciamento do Bean para o Spring
Controlando a inicialização do nosso objeto, o Spring todas as tarefas de gerenciamentos requeridas por aplicações J2EE
Isso, claro, antes que nosso objeto seja utilizado pela aplicação
Em prática
springconfig.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> </bean> <!-- Bean Classes --> <bean id="beanTarget" class="BusinessLogic"/></beans>
Em prática
Diagrama de seqüência
Em prática
Implementando um Adviceimport java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;
public class TracingBeforeAdvice implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) throws Throwable {
System.out.println("Hello world! (by " + this.getClass().getName() + ")"); }}
Em prática
Para acoplar o Advice a determinados joinpoints de nossa aplicação prescisamos acrescentar algumas declarações no springconfig.xml... <!-- Advisor pointcut definition for before advice --> <bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingBeforeAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean>
<!-- Advice classes --> <bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice"/>...
Aplicado porexpressões regulares!
Em prática
springconfig.xml (cont.) <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> <property name="interceptorNames"> <list> <value>theTracingBeforeAdvisor</value> </list> </property> </bean>
Em prática
springconfig.xml (cont.)
Chamada transparente ao Advice do aspecto
E ainda
Existem ainda outras formas de aplicar aspectos com o Spring AutoProxy:
BeanNameAutoProxyCreator DefaultAdvisorAutoProxyCreator
Conclusões
AOP com o Spring tem sido aplicado a vários projetos
AOP melhora consideravelmente a qualidade de um sistema, aumentando a simplicidade do modelo
AOP está pegando
Exercícios
Rode o exemplo mostrado Implemente um log para nosso sistema com AOP
Introdução a AOP + SpringAOP
Jobson Ronan {jrjs@cin.ufpe.br}