300 likes | 395 Views
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.
E N D
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
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 Advice import 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 por expressõ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}