`
hlxiong
  • 浏览: 33140 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Spring Framework中的面向方面编程(AOP),第一部分

阅读更多
作为这个介绍Spring框架中的面向方面编程(Aspect-Oriented Programming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面(面向方面领域的HelloWorld)作为例子,本文展示了如何使用Spring框架所独有的特性来声明切入点和通知以便应用方面。本系列的第二部分将更深入地介绍如何运用Spring中的所有通知类型和切入点来实现更实用的方面和面向方面设计模式。对于AOP的更一般性的介绍,请查看ONJava站点上Graham O'Regan的文章,“Introduction to Aspect-Oriented Programming”。

  本文的目的不是要介绍构成模块化J2EE系统——即Spring框架——的所有重要元素,我们将只把注意力放在Spring所提供的AOP功能上。由于Spring的模块化设计方法,我们可以只使用该框架的AOP元素,而无需对构成Spring框架的其他模块做太多考虑。

在AOP方面,Spring提供了什么?
  “它的目标不是提供最完善的AOP实现(虽然Spring AOP非常强大);而是要提供AOP实现与Spring IoC的紧密集成,以便企业应用中的常见问题。”
Spring Framework参考文档

  为了实现这个目标,Spring框架目前支持一组AOP概念,从切入点到通知。本文将展示如何使用Spring框架中所实现的如下AOP概念:

  • 通知(Advice):如何将before通知、afterReturning通知和afterThrowing通知声明为bean。
  • 切入点(Pointcut):如何声明静态切入点逻辑以将XML Spring Bean Configuration文件中的所有内容联系在一起。
  • Advisor关联切入点定义与通知bean的方式。

设置场景:一个简单的例子应用程序
  “一般而言,Spring并不是预描述的。虽然使用好的实践非常容易,但是它避免强制推行一种特定的方法。”
Spring Framework参考文档

  要试用Spring框架的AOP功能,首先我们要创建一个简单的Java应用程序。IbusinessLogic接口和BusinessLogic类为Spring框架中的bean提供了简易构件块。虽然该接口对于我们的简单应用程序逻辑来说不是必需的,但是它是Spring框架所推荐的良好实践。

public interface IBusinessLogic
{
    public void foo();
}

public class BusinessLogic 
    implements IBusinessLogic
{
    public void foo() 
    {
        System.out.println(
        "Inside BusinessLogic.foo()");
    }
}

  可以编写MainApplication类,借此练习BusinessLogic bean的公有方法。

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();
    }
}

  在BusinessLogic类及其关联接口中没有什么需要注意的。但是,MainApplication类初始化BusinessLogic对象的方式很有意思。通过使用ctx.getBean("businesslogicbean")调用,MainApplication将加载和管理BusinessLogic类的bean实例的任务转交给了Spring框架。

  允许Spring控制BusinessLogic bean的初始化,这使得Spring运行时有机会在bean被返回给应用程序之前执行J2EE系统所需的所有与bean相关的管理任务。然后Spring运行时配置可以决定对bean应用哪些任务和模块。该配置信息由一个XML文件提供,类似于下面所示的:

xml 代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC   
  3.     "-//SPRING//DTD BEAN//EN"   
  4.     "http://www.springframework.org/dtd/spring-beans.dtd">  
  5.   
  6. <beans>  
  7.   
  8.    <!-- Bean configuration -->  
  9.    <bean id="businesslogicbean"  
  10.    class="org.springframework.aop.framework.ProxyFactoryBean">  
  11.       <property name="proxyInterfaces">  
  12.          <value>IBusinessLogic</value>  
  13.       </property>  
  14.       <property name="target">  
  15.          <ref local="beanTarget"/>  
  16.       </property>  
  17.    </bean>  
  18.    <!-- Bean Classes -->  
  19.    <bean id="beanTarget"  
  20.    class="BusinessLogic"/>  
  21.   
  22. </beans>  

  该配置文件,即springconfig.xml,指定要加载一个接口与IbusinessLogic相匹配的bean。该bean随后被关联到BusinessLogic实现类。看起来好像是费了很大力气只为了加载一个简单的bean并调用一个方法,但是您要知道,这个配置文件只是使Spring框架可以透明地对应用程序应用其组件的众多特性的一个体现。

  图1显示了基本的顺序图:MainApplication原样执行,没有应用方面。

Figure 1
图1.没有对BusinessLogic bean应用方面时的顺序图

  请查看本文末尾处的参考资料,获取这个简单Spring应用程序的源代码。

应用方法跟踪(Method Tracing)方面
  可能最基本的方面就是方法跟踪方面了。这可能是您找得到的最简单的方面了,因此它是研究新的AOP实现的一个很好的起点。

  方法跟踪方面在一个目标应用程序内捕获对所跟踪的方法的调用以及方法的返回值,并以某种方式显示这种信息。在AOP中,通知的before和after类型用于捕获这些类型的联结点,因为这两种通知可以在方法调用联结点之前或之后触发。使用Spring框架,方法跟踪方面的before通知是在TracingBeforeAdvice类中声明的。

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() + 
          ")");
    }
}

  类似地,after通知可以在TracingAfterAdvice类中声明。

import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class TracingAfterAdvice 
   implements AfterReturningAdvice
{
    public void afterReturning(Object object, 
                             Method m, 
                             Object[] args, 
                             Object target) 
                             throws Throwable
    {
        System.out.println(
          "Hello world! (by " + 
          this.getClass().getName() + 
          ")");
    }
}

  这两个类都通过实现Spring框架的适当通知接口而表示了特定的通知。每种类型的通知都指定实现before(..)或afterReturning(..)方法,以便使Spring运行时可以告诉通知适当的联结点会在何时出现。值得注意的是,TracingAfterAdvice实际上是从AfterReturningAdvice扩展而来的,表示只有在联结点在无异常的情况下获得返回值时才运行通知。

  为了将通知与应用程序中的适当联结点关联起来,必须对springconfig.xml进行一些修改。

<!---->
  1. <!---->xml version="1.0" encoding="UTF-8"?>  
  2. <!---->
  3.     "-//SPRING//DTD BEAN//EN"   
  4.     "http://www.springframework.org/dtd/spring-beans.dtd">  
  5.   
  6. <beans>  
  7.   
  8.    <!---->  
  9.    <bean id="businesslogicbean"  
  10.    class="org.springframework.aop.framework.ProxyFactoryBean">  
  11.       <property name="proxyInterfaces">  
  12.          <value>IBusinessLogicvalue>  
  13.       property>  
  14.       <property name="target">  
  15.          <ref local="beanTarget"/>  
  16.       property>  
  17.       <property name="interceptorNames">  
  18.          <list>  
  19.             <value>theTracingBeforeAdvisorvalue>  
  20.             <value>theTracingAfterAdvisorvalue>  
  21.          list>  
  22.          property>  
  23.    bean>  
  24.    <!---->  
  25.    <bean id="beanTarget"  
  26.    class="BusinessLogic"/>  
  27.   
  28.    <!---->  
  29.    <bean id="theTracingBeforeAdvisor"  
  30.       class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  31.       <property name="advice">  
  32.          <ref local="theTracingBeforeAdvice"/>  
  33.       property>  
  34.       <property name="pattern">  
  35.          <value>.*value>  
  36.       property>  
  37.    bean>  
  38.        
  39.    <!---->  
  40.    <bean id="theTracingAfterAdvisor"  
  41.       class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
  42.       <property name="advice">  
  43.          <ref local="theTracingAfterAdvice"/>  
  44.       property>  
  45.       <property name="pattern">  
  46.          <value>.*value>  
  47.       property>  
  48.    bean<  
  49.   
  50.    <!---->  
  51.    <bean id="theTracingBeforeAdvice"  
  52.       class="TracingBeforeAdvice"/>  
  53.    <bean id="theTracingAfterAdvice"  
  54.       class="TracingAfterAdvice"/>  
  55.   
  56. beans>  
xml 代码

  theTracingBeforeAdvisor和theTracingAfterAdvisor advisor被添加到前面所声明的businesslogicbean。每个advisor都可能截获所有bean所关联到的联结点。Advisor本身就是bean,而它唯一的作用就是将切入点定义与通知bean关联起来。本例中的切入点定义是在静态对象层次结构中指定相关联结点的正则表达式。

  因为本例中使用了org.springframework.aop.support.RegexpMethodPointcutAdvisor切入点advisor,切入点逻辑是使用正则表达式指定的。正则表达式用于识别公有接口对IbusinessLogici接口的联结点。下面是一些可以用来指定IBusinessLogic接口上的不同联结点集合的正则表达式例子:

  • <value></value>.*该表达式选择advisor所关联到的一个或多个bean上的所有联结点。
  • <value></value>./IBusinessLogic/.foo该表达式只选择IbusinessLogic接口上的foo()方法的联结点。如果是advisor所关联到的bean,则该表达式只选择IBusinessLogic接口上的联结点。

  springconfig.xml文件中最后的bean声明指定实现通知bean的类。

  既然已经指定了跟踪方面的正确配置,那么下一次执行MainApplication时,这些方面就会在初始化过程中被编织进去,而BusinessLogic bean中的所有方法都将被跟踪,如图2所示。

  Click for larger view
图2. 方法跟踪方面应用到BusinessLogic bean之后的顺序图(单击图像查看大图)

  方法跟踪方面和例子应用程序的源代码可在本文末尾的参考资料小节进行下载。

方面的重用
  可以对方法跟踪方面进行扩展,提供一个稍微复杂的记录(Logging)方面。记录方面提供了一个很不错的重用例子,因为记录方面所需的许多特性都已经包含在方法跟踪方面中了。

  在本例中,记录方面扩展了方法跟踪方面,以便显示附加的与(在应用程序的执行过程中)所引发的异常有关的信息。

  要完全使用记录方面,需要对应用程序做一些更改。BusinessLogicException异常类提供了一个可以由IBusinessLogicInterface接口和BusinessLogic实现类新增的void bar()方法引发的异常。

public class BusinessLogicException 
   extends Exception
{

}

public interface IBusinessLogic
{
    public void foo();
   
    public void bar() 
      throws BusinessLogicException;
}

public class BusinessLogic 
   implements IBusinessLogic
{
    public void foo() 
    {
        System.out.println(
          "Inside BusinessLogic.foo()");
    }
     
    public void bar() 
       throws BusinessLogicException
    {
        System.out.println(
        "Inside BusinessLogic.bar()");
          throw new BusinessLogicException();
    }
}

  MainApplication类现在将对void bar()方法进行一次额外的调用,并处理选中的、可能由该方法引发的异常。

import org.springframeworkcontext.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 methods of the bean
       testObject.foo();
      
       try
       {
           testObject.bar();
       }
       catch(BusinessLogicException ble)
       {
           System.out.println(
             "Caught BusinessLogicException");
       }
    }
}

  来自方法跟踪方面的TracingBeforeAdvice和TracingAfterAdvice通知可以整体重用。LoggingThrowsAdvice类为新的异常记录提供了通知。

import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;

public class LoggingThrowsAdvice 
   implements ThrowsAdvice
{
    public void afterThrowing(Method method, 
                            Object[] args, 
                            Object target, 
                            Throwable subclass)
    {
       System.out.println(
         "Logging that a " + 
         subclass + 
         "Exception was thrown.");
    }
}

  应用记录方面的最后一步是修改springconfig.xml配置文件,使其包含新添加的LoggingThrowsAdvice通知。

  图3显示了运行MainApplication并使用Spring框架应用了记录方面的UML顺序图。

  Click for larger view
图3. 记录方面应用到BusinessLogic bean之后的顺序图(单击图像查看大图)

  此处的记录方面清楚地说明了如何重用现有方面以及如何在Spring框架中使用通知的throws形式。通过为before和after通知声明新的通知来重写现有的方法跟踪方面实现,可以实现更复杂的记录方面,记录到更复杂的记录框架,比如LOG4J。关于记录方面和例子应用程序的源代码,请参见本文末尾的参考资料小节。

结束语
  本文展示了使用Spring框架中的基本AOP结构所应用的一些简单方面。在本系列的下一篇文章中,我们将介绍一些更实用的方面,探讨方面的生命周期,使用Spring框架的around通知,并使用Spring来应用AOP模式。

  参考资料

  原文出处:An Introduction to Aspect-Oriented Programming with the Spring Framework, Part 1http://www.onjava.com/pub/a/onjava/2004/07/14/springaop.html

 作者简介
  Russell Miles是General Dynamics UK公司的一名软件工程师,他负责Java和分布式系统,但是他目前主要的兴趣在面向方面领域,尤其是AspectJ。

[摘自]http://dev2dev.bea.com.cn/techdoc/20051216709.html
分享到:
评论

相关推荐

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)...对于希望深入了解Spring AOP原理与实践的读者来说,掌握以上概念将是开启面向方面编程之旅的第一步。

    SpringFramework中的面向方面编程(AOP),第一部分

    作为这个介绍Spring框架中的面向方面编程(Aspect-OrientedProgramming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面(面向方面领域的Hello...

    SpringFramework中的面向方面编程(AOP),第二部分

    火龙果软件工程技术中心 在本系列的第一部分,我介绍了如何实现面向方面领域的“HelloWorld”:跟踪和记录方面。利用Spring框架所提供的面向方面编程(Aspect-OrientedProgramming,AOP)功能,您看到了如何使用...

    spring Framework 中文参考开发手册

    AOP 是 Spring 提供的一种编程模型,用于处理系统中的横切关注点,如日志、事务管理等。AOP 将这些关注点与业务逻辑分离,使得代码更加整洁,提高了模块化程度。Spring AOP 使用代理模式实现,支持基于注解和基于...

    spring framework 简介

    - **面向切面编程(AOP)**:Spring 支持面向切面编程,使得开发者能够在不影响核心业务逻辑的情况下添加如日志记录、事务管理等功能。 - **数据访问抽象**:Spring 提供了一套强大的数据访问抽象层,简化了对各种...

    Spring Framework开发中文参考文档

    10. **Web服务**:Spring Web Services模块允许开发者创建基于WSDL(Web Services Description Language)的第一类公民的SOAP服务,并提供了XPath和XSLT支持,以及对WS-Security等Web服务安全标准的集成。...

    spring-framework-5.3.23 源码

    面向切面编程(Aspect-Oriented Programming,简称AOP)是Spring提供的另一大特性。AOP允许开发者将关注点(如日志、事务管理)与核心业务逻辑分离,通过定义切面来实现。Spring AOP支持在方法执行前后、异常处理等...

    SpringFramework中的AOP编程之入门篇

    作为这个介绍Spring框架中的面向方面编程(Aspect-OrientedProgramming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面(面向方面领域的Hello...

    第五章:Spring AOP 在 Spring Framework 内部应用1

    Spring AOP,即Aspect Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下对程序进行功能增强的技术。本章主要探讨了Spring AOP在Spring框架内部的多种应用,...

    springframework

    标题中提到的"springframework"指的是Spring Framework,它是Spring生态系统的基础,提供依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented Programming,AOP)和一系列的企业级服务,如数据...

    spring-framework-4.2.3.RELEASE

    Spring Framework,作为Java开发中的核心框架,以其强大的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)功能,极大地提升了企业级应用的开发效率。本文将深入探讨Spring...

    使用Spring Framework 设计和开发 SCA 组件,第 1 部分.pdf.pdf

    2. **更好的可维护性和可扩展性**:通过使用Spring的依赖注入(DI)和面向切面编程(AOP),可以更容易地管理和扩展SCA组件。 3. **简化部署**:SCA提供了一种简单的方式来部署和管理服务组件。Spring Framework ...

    spring-framework-5.0.2.RELEASE官方完整包加官方文档

    Spring Framework的核心特性包括依赖注入(Dependency Injection, DI)、面向切面编程(Aspect-Oriented Programming, AOP)、模型-视图-控制器(Model-View-Controller, MVC)架构模式,以及对Java EE标准和第三方...

    spring-framework-3.0.6

    Spring Framework 3.0.6 是一个里程碑式的版本,它在Java企业级开发中扮演着至关重要的角色。作为一款开源、轻量级的框架,Spring 提供了丰富的功能,帮助开发者构建可维护、可扩展且易于测试的应用程序。在本文中,...

    Spring Framework5.2.9 API 网页版

    2. **AOP(Aspect-Oriented Programming)**:Spring支持面向切面编程,允许定义“切面”——关注点的模块化,如日志、事务管理等,可以独立于业务逻辑进行处理。 3. **数据访问/集成**:Spring提供了JDBC抽象层,...

    spring-framework-3.0.2-dependencies

    Spring 框架是Java开发领域中不可或缺的一部分,它提供了一个全面的编程和配置模型,旨在简化企业级应用的创建和维护。Spring 3.0.2 是该框架的一个重要版本,虽然它已经不再更新,但依然在许多现有的项目中被广泛...

    spring-framework-5.0.5

    在模块化方面,Spring Framework 5.0.5 提供了更清晰的模块划分,包括核心容器(Core Container)、数据访问/集成(Data Access/Integration)、Web、AOP(面向切面编程)和测试等模块。其中,核心容器包括Bean工厂...

Global site tag (gtag.js) - Google Analytics