`

AOP的学习

阅读更多

        AOP正在成为软件开发的下一个圣杯。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。
        为了理解AOP如何做到这点,考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中,那该多好啊。AOP可以帮助你做到。
        Spring framework是很有前途的AOP技术。作为一种非侵略性的,轻型的AOP framework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework,其他人还是象往常一样编程。
AOP是很多直觉难以理解的术语的根源。幸运的是,你只要理解三个概念,就可以编写AOP模块。这三个概念是:advice,pointcut和 advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置,通常是某个特定的类的一个 public方法。advisor是pointcut和advice的装配器,是将advice注入主程序中预定义位置的代码。

既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice,让我们实现一个Spring AOP的例子。在这个例子中,我们将实现一个before advice,这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码:

java 代码
  1. package com.company.springaop.test;   
  2.   
  3. import java.lang.reflect.Method;   
  4. import org.springframework.aop.MethodBeforeAdvice;   
  5.   
  6. public class TestBeforeAdvice implements MethodBeforeAdvice {   
  7.   
  8.   public void before(Method m, Object[] args, Object target)   
  9.   throws Throwable {   
  10.     System.out.println("Hello world! (by "  
  11.         + this.getClass().getName()   
  12.         + ")");   
  13.   }   
  14. }   


        接口MethodBeforeAdvice只有一个方法before需要实现,它定义了advice的实现。before方法共用三个参数,它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时,参数args和被执行方法的名称,都是非常有用的信息。你也可以改变传给m的参数,但要小心使用这个功能;编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。

在下面的BeanImpl类中,每个public方法调用前,都会执行advice:

java 代码
  1. package com.company.springaop.test;   
  2.   
  3. public class BeanImpl implements Bean {   
  4.   
  5.   public void theMethod() {   
  6.     System.out.println(this.getClass().getName()   
  7.         + "." + new Exception().getStackTrace()[0].getMethodName()   
  8.         + "()"  
  9.         + " says HELLO!");   
  10.   }   
  11. }   


类BeanImpl实现了下面的接口Bean:

java 代码
  1. package com.company.springaop.test;   
  2.   
  3. public interface Bean {   
  4.   public void theMethod();   
  5. }   


虽然不是必须使用接口,但面向接口而不是面向实现编程是良好的编程实践,Spring也鼓励这样做。

pointcut和advice通过配置文件来实现,因此,接下来你只需编写主方法的Java代码:
    java 代码

  1. package com.company.springaop.test;   
  2.   
  3. import org.springframework.context.ApplicationContext;   
  4. import org.springframework.context.support.FileSystemXmlApplicationContext;   
  5.   
  6. public class Main {   
  7.   
  8.   public static void main(String[] args) {   
  9.     //Read the configuration file   
  10.     ApplicationContext ctx   
  11.         = new FileSystemXmlApplicationContext("springconfig.xml");   
  12.   
  13.     //Instantiate an object   
  14.     Bean x = (Bean) ctx.getBean("bean");   
  15.   
  16.     //Execute the public method of the bean (the test)   
  17.     x.theMethod();   
  18.   }   
  19. }   



我们从读入和处理配置文件开始,接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后,我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。

仅仅用配置文件便可把程序的每一部分组装起来

xml 代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
  3.   
  4. <beans>  
  5.   <!--CONFIG-->  
  6.   <bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">  
  7.     <property name="proxyInterfaces">  
  8.       <value>com.company.springaop.test.Bean</value>  
  9.     </property>  
  10.     <property name="target">  
  11.       <ref local="beanTarget"/>  
  12.     </property>  
  13.     <property name="interceptorNames">  
  14.       <list>  
  15.         <value>theAdvisor</value>  
  16.       </list>  
  17.     </property>  
  18.   </bean>  
  19.   
  20.   <!--CLASS-->  
  21.   <bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>  
  22.   
  23.   <!--ADVISOR-->  
  24.   <!--Note: An advisor assembles pointcut and advice-->  
  25.   <bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  26.     <property name="advice">  
  27.       <ref local="theBeforeAdvice"/>  
  28.     </property>  
  29.     <property name="pattern">  
  30.       <value>com\.company\.springaop\.test\.Bean\.theMethod</value>  
  31.     </property>  
  32.   </bean>  
  33.   
  34.   <!--ADVICE-->  
  35.   <bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/>  
  36. </beans>  

四个bean定义的次序并不重要。我们现在有了一个advice,一个包含了正则表达式pointcut的advisor,一个主程序类和一个配置好的接口,通过工厂ctx,这个接口返回自己本身实现的一个引用。

BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素,并指定了一个实现类。这就是全部的工作。

advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的 advice-bean。第二个属性则用正则表达式定义了pointcut,确保良好的性能和易读性。

最后配置的是bean,它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现,它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义:
    * 属性proxyInterface定义了接口类。
    * 属性target指向本地配置的一个bean,这个bean返回一个接口的实现。
    * 属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意,advisor列表的次序是非常重要的。

Spring工具

虽然你可以手工修改Ant构建脚本,但使用SpringUI(译注:SpringUI现在是Spring framework的一部分,并改名为spring-ide),使用Spring AOP变得很简单,只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后,你只需在你的project上右击鼠标,并选择“add Spring Project Nature”。在project属性中,你可以在“Spring Project”下添加Spring配置文件。在编译前把下面的类库加入project:aopalliance.jar,commons- logging.jar,jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息:

... (logging information)
Hello world! (by com.company.springaop.test.TestBeforeAdvice)
com.company.springaop.test.BeanImpl.theMethod() says HELLO!


优点和缺点

Spring比起其他的framework更有优势,因为除了AOP以外,它提供了更多别的功能。作为一个轻型framework,它在J2EE 不同的部分都可以发挥作用。因此,即使不想使用Spring AOP,你可能还是想使用Spring。另一个优点是,Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一页开始。读了本文后,你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档,但它的mailing list是个很好的补充,而且会不断地出现更多的文档。

分享到:
评论

相关推荐

    Spring IOC AOP学习示例

    Spring IOC AOP学习示例代码,包含Spring常用操作示例和所有所需jar文件。参考博客:http://blog.csdn.net/daijin888888/article/details/51735291

    spring aop 学习笔记

    本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...

    aop学习

    面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在将关注点分离,使得系统中的横切关注点,如日志、事务管理、权限检查等,可以从核心业务逻辑中解耦出来。AOP的核心概念包括切面、连接点、...

    C# AOP学习DEMO

    在"C# AOP学习DEMO"中,很可能是通过上述的一种或多种方式展示了AOP的实践。DEMO可能包含了如何定义切面、如何应用切面、如何处理横切关注点等内容。例如,它可能包括了以下部分: - 特性的定义和使用:创建自定义...

    SpringAop学习笔记以及实现Demo

    **Spring AOP 学习笔记及实现Demo** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的主要目的...

    Spring AOP学习资料(pdf)

    ### Spring AOP 学习资料知识点总结 #### 一、Spring AOP 概念与背景 **Spring AOP**(面向切面编程)是Spring框架中的一个重要组成部分,它通过预定义的切入点来分离关注点,使得核心业务逻辑更加清晰,同时能够...

    2024-spring-aop学习项目

    《深入理解Spring AOP:2024春季学习项目指南》 ...通过这个2024春季AOP学习项目,开发者将有机会亲手实践上述概念,深入理解Spring AOP的精髓,从而在实际项目中更好地运用这一强大的工具,提升代码质量与工程效率。

    spring aop学习实例

    **Spring AOP学习实例** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP允许开发者定义“切面”...

    spring AspectJ aop学习

    当我们谈论"spring AspectJ aop学习"时,我们将深入探讨Spring AOP如何结合AspectJ来实现更灵活的模块化和解耦。 首先,让我们理解AOP的概念。面向切面编程(Aspect Oriented Programming)是一种编程范式,旨在将...

    Spring Aop 学习笔记

    Spring Aop 学习笔记

    springaop学习

    ### Spring AOP 学习知识点详解 #### 一、Spring AOP 原理 **Spring AOP**(面向切面编程)是 Spring 框架中的一个关键特性,它提供了一种优雅的方式来处理横切关注点(cross-cutting concerns)。在实际应用中,...

    AOP学习笔记

    《AOP学习笔记》 在软件开发中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种重要的编程范式,它旨在提高代码的可读性和可维护性,通过将关注点分离来实现模块化。AOP的核心概念是切面、连接点、...

    SSH+AOP学习资料源码

    通过学习和实践这些SSH+AOP的资料源码,开发者可以提升自己在Java Web开发领域的技能,理解如何利用Spring管理依赖,使用Struts处理Web请求,借助Hibernate操作数据库,以及如何运用AOP来增强代码的灵活性和可维护性...

    Spring AOP学习笔记

    NULL 博文链接:https://linres.iteye.com/blog/281221

    面向方法编程AOP学习之二 —— “原始时代”

    在这一阶段,程序员们开始意识到将程序分解为一系列独立的功能模块或方法的重要性,但尚未发展出如面向切面编程(Aspect-Oriented Programming,AOP)等更为先进的技术。 在面向方法编程的“原始时代”,开发者主要...

    [#0x0042] Spring AOP学习(二):动态代理

    在Spring AOP的学习中,动态代理是一个至关重要的概念。本文将深入探讨动态代理在Spring框架中的应用,以及如何通过JDK的动态代理机制实现这一功能。动态代理是面向切面编程(AOP)的一种实现方式,它允许我们在不...

    aopmock:aop学习记录并简单模仿实现

    《AOPMock:AOP学习与简易实现解析》 在软件开发中,面向切面编程(Aspect Oriented Programming,简称AOP)是一种重要的设计模式,它允许程序员将关注点从核心业务逻辑中分离出来,专注于系统的横切关注点,如日志...

Global site tag (gtag.js) - Google Analytics