正 文

Spring Framework中的AOP之around通知


www.7dspace.com  更新日期:2005-12-30 7:12:40  七度空间


  要使用Spring AOP实现Cuckoo's Egg设计模式,需要声明一个around通知来截获所有对要置换的功能部件的调用。与hot-swappable target sources(Spring AOP的一个功能部件,将在本系列的另一篇文章中介绍)不同,around通知的显式使用使得Cuckoo's Egg实现可以有效地跨越对象边界(因此也可以跨越bean边界)进行整个功能部件的置换,如图7所示。

Figure 7
图7. 一个跨越bean边界的组件

  图字:

  A feature crosses the boundaries of BusinessLogic and BusinessLogic2 by depending on behavior supplied separately by the two beans:一个功能部件通过依赖于由BusinessLogic和BusinessLogic2各自提供的行为而跨越了这两个bean的边界

  下面的代码显示了一个具有两个bean的简单应用程序,其中有一个功能部件跨越了该应用程序的多个方面。要置换的功能部件可以被视为包含 IBusinessLogic bean中的foo()方法和IBusinessLogic2 bean中的bar()方法。IBusinessLogic2 bean中的baz()方法不是 该功能部件的一部分,所以不进行置换。

public interface IBusinessLogic
{
   public void foo();
}

public interface IBusinessLogic2
{
   public void bar();
   
   public void baz();
}

  此处,ReplacementFeature类扮演了“杜鹃的蛋”的角色,它提供了将被透明地引入应用程序的替代实现。ReplacementFeature类实现了所有在该类引入时要被置换的方法。

public class ReplacementFeature
{
   public void foo()
   {
      System.out.println(
         "Inside ReplacementFeature.foo()");
   }
   
   public void bar()
   {
      System.out.println(
         "Inside ReplacementFeature.bar()");
   }
}

  现在需要声明一个around通知来截获对跨越bean的功能部件的方法调用。CuckoosEgg类提供了某种around通知来检查被截获的方法,并将适当的方法调用传递给ReplacementFeature类的实例。

public class CuckoosEgg implements MethodInterceptor
{
   public ReplacementFeature replacementFeature =
       new ReplacementFeature();
   
   public Object invoke(MethodInvocation invocation)
       throws Throwable
   {
      if (invocation.getMethod().getName().equals("foo"))
      {
         replacementFeature.foo();
      }
      else
      {
         replacementFeature.bar();
      }
      
      return null;
   }
}

  因为与Spring框架关系密切,Cuckoo's Egg设计的详细信息被放在springconfig.xml配置文件中。对springconfig.xml文件的更改将确保所有对 IbusinessLogic和IBusinessLogic2 bean的foo()方法和bar()方法的调用都将被截获,并传递给CuckoosEgg类的around通知。

   ...
   
   <!--CONFIG-->
   <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>theCuckoosEggAdvisor</value>
         </list>
      </property>
   </bean>
   
   <bean id="businesslogicbean2" 
      class="org.springframework.aop.framework.ProxyFactoryBean">
      <property name="proxyInterfaces">
         <value>IBusinessLogic2</value>
      </property>
      <property name="target">
         <ref local="beanTarget2"/>
      </property>
      <property name="interceptorNames">
         <list>
            <value>theCuckoosEgg2Advisor</value>
         </list>
      </property>
   </bean>

   <!--CLASS-->
   <bean id="beanTarget" class="BusinessLogic"/>
   <bean id="beanTarget2" class="BusinessLogic2"/>
   
   <!--ADVISOR-->
   <bean id="theCuckoosEggAdvisor" 
      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="advice">
         <ref local="theReplacementFeaturePart1Advice"/>
      </property>
      <property name="pattern">
         <value>IBusinessLogic.*</value>
      </property>
   </bean>
   
   <bean id="theCuckoosEgg2Advisor" 
      class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="advice">
         <ref local="theReplacementFeaturePart2Advice"/>
      </property>
      <property name="pattern">
         <value>IBusinessLogic2.bar*</value>
      </property>
   </bean>
   
   <!--ADVICE-->
   <bean id="theReplacementFeaturePart1Advice" class="CuckoosEgg"/>
   <bean id="theReplacementFeaturePart2Advice" class="CuckoosEgg"/>
   
   ...

  当使用修改后的springconfig.xml文件运行例子应用程序时,要替换的、被指定为功能部件的一部分的方法调用完全被截获并传递给ReplacementFeature类。

  通常,即使在同一个实现环境中,我们也可以用不同的方法来实现同一种设计模式。实现上例的另一种方法是实现两个独立的通知。

  最后需要注意的是,使用Cuckoo's Egg设计模式置换的功能部件,不管它是跨越bean的还是在一个类中,它的生命周期与它所置换的功能部件的目标生命周期匹配。在上例中这没什么问题,因为只有一个功能部件实例被置换了,而且唯一的Cuckoo's Egg通知只维护一个替代功能部件。

  这个例子非常简单,而在实践中,您很可能必须处理大量需要用各自的Cuckoo's Egg实例置换的功能部件实例。在这种情况下,单个的方面实例需要被关联到单个的要置换的功能部件实例。本系列的下一篇文章将会考虑方面生命周期的用法,届时将解决这个问题。

  结束语

  本文介绍了如何在Spring框架内谨慎使用around形式的通知。around形式的通知常用于实现Cuckoo's Egg设计模式时,所以我们引入了一个例子来说明如何使用Spring AOP实现这种面向方面设计模式。

  在本系列的第三部分中,您将看到如何使用Spring框架中其他的AOP基本概念。这些概念包括:控制方面生命周期、使用基于introduction通知的积极方面改变应用程序的静态结构,以及使用control flow切入点实现对方面编织的更细微的控制。

4页,页码:[1] [2] [3] [4] 

上一篇:Visual Basic .Net打造个性化菜单
下一篇:Excel中快速输入有规律的数据
作者:Binildas Christudas  来源:BEA ( 责任编辑:7dspace )
收藏此页】【打印】【关闭
站 内 搜 索
 

热 点 导 读
特 别 推 荐