`
liusg123
  • 浏览: 17860 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring Gossip: IntroductionInterceptor

阅读更多
对于之前介绍过的Before Advice、After Advice、Around Advice、Throw Advice,从使用者的角度来看,它们“影响了目标物件上某些方法的行为”,例如让某些方法看来似乎增加了一些记录的动作。

Introduction是个特别的Advice,从使用者的角度来看,它“影响了目标物件的行为定义,直接增加了目标物件的职责(具体来说就是增加了可操作的方法)”,例如让某个已定义好的物件,在不修改该物件之类别档案的情况下,却可以增加一些额外的操作方法到物件之上。

就Java程式语言类别设计的观点来说,动态为物件增加可操作的方法显得不可思议,事实上在Spring AOP中,您可以透过实作org.springframework.aop.IntroductionInterceptor来实现Introduction。

IntroductionInterceptor继承了MethodInterceptor与DynamicIntroductionAdvice介面,其中implementsInterface()方法(继承自DynamicIntroductionAdvice)如果返回true的话,表示目前的 IntroductionInterceptor实作了给定的介面(也就是要额外增加行为的介面),此时您要使用invoke()呼叫介面上的方法,让目标物件执行额外的行为,您不可能使用MethodInvocation的proceed()方法,因为您要执行的是物件上原来没有的行为,呼叫 proceed()方法没有意义。

从文字上来理解Introduction会比较抽象,举个实际的例子来说,假设您的系统中已经有以下的类别:

    * ISome.java

package onlyfun.caterpillar;

public interface ISome {
    public void doSome();
}


    * Some.java

package onlyfun.caterpillar;

public class Some implements ISome {
    public void doSome() {
        System.out.println("原来物件的职责。。。");
    }
}


您希望在不修改原始档案的情况下,为Some类别增加一些可操作的方法,也许您甚至连原始码档案都没有,只有.class档案,您唯一知道的也许是他们的API说明,在不对它们作出修改的情况下,您希望Some类别可以增加doOther()方法。

在Spring中,您可以藉由实作IntroductionInterceptor介面来完成上面的任务,首先您为doOther()方法建立介面:

    * IOther.java

package onlyfun.caterpillar;

public interface IOther {
    public void doOther();
}


接着定义一个OtherIntroduction类别实作IntroductionInterceptor介面,并在实作IntroductionInterceptor介面的同时,也实作IOther介面,例如:

    * OtherIntroduction.java

package onlyfun.caterpillar;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;

public class OtherIntroduction
              implements IntroductionInterceptor, IOther { 
    // 是否实作自IOther介面
    public boolean implementsInterface(Class clazz) {
        return clazz.isAssignableFrom(IOther.class);
    }
  
    public Object invoke(MethodInvocation methodInvocation)
                                      throws Throwable {
        // 如果呼叫的方法来自IOther介面的定义
        if(implementsInterface(methodInvocation.getMethod().getDeclaringClass())) {
            // 呼叫执行额外加入(mixin)的行为
            return methodInvocation.getMethod().invoke(this, methodInvocation.getArguments());
        }
        else {
            return methodInvocation.proceed();
        }
    }
  
    public void doOther() {
        System.out.println("增加的职责。。。");
    }
}


接着您要在Bean定义档中将Introduction缝合至Some物件之上,使用org.springframework.aop.support.DefaultIntroductionAdvisor就可以了,例如:

    * beans-config.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 id="some"
          class="onlyfun.caterpillar.Some"/>

    <bean id="otherIntroduction"
          class="onlyfun.caterpillar.OtherIntroduction"/>
        
    <bean id="otherAdvisor"
          class="org.springframework.aop.support.DefaultIntroductionAdvisor">
          <constructor-arg index="0">
              <ref bean="otherIntroduction"/>
          </constructor-arg>
          <constructor-arg index="1">
              <value>onlyfun.caterpillar.IOther</value>
          </constructor-arg>
    </bean>
 
    <bean id="proxyFactoryBean"
          class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>onlyfun.caterpillar.ISome</value>
        </property>
        <property name="target">
            <ref bean="some"/>
        </property>
        <property name="interceptorNames">  DefaultIntroductionAdvisor的bean id
            <list>
                <value>otherAdvisor</value>
            </list>
        </property>
    </bean>
</beans>

DefaultIntroductionAdvisor在建构时,需要给它IntroductionInterceptor的实例,以及所要代理额外行为的介面,现在,来撰写一个简单的程式测试,从这个程式当中,您可以更进一步了解何谓为物件额外增加行为:

    * SpringAOPDemo.java

package onlyfun.caterpillar;

import org.springframework.context.ApplicationContext;
import org.springframework.context.
              support.FileSystemXmlApplicationContext;

public class SpringAOPDemo {
    public static void main(String[] args) {
        ApplicationContext context =
            new FileSystemXmlApplicationContext("beans-config.xml");
  
        ISome some = (ISome) context.getBean("proxyFactoryBean");
  
        some.doSome();
  
        // 看来好像some物件动态增加了职责
        ((IOther) some).doOther();
    }
}

对于some所参考的物件来说,它原先并不会有doOther()方法可供操作,然而透过Spring AOP的Introduction机制,现在some所参考的物件多了doOther()方法可以操作。(introduction解释为传入)
分享到:
评论

相关推荐

    Java经典问题算法大全

    2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八...

    经典算法大全.pdf

    巴斯卡三角形 6 4.Algorithm Gossip: 三色棋 7 5.Algorithm Gossip: 老鼠走迷官(一) 9 6.Algorithm Gossip: 老鼠走迷官(二) 11 7.Algorithm Gossip: 骑士走棋盘 13 8.Algorithm Gossip: 八皇后 ...

    经典算法大全

    2.Algorithm Gossip: 费式数列 5 3. 巴斯卡三角形 6 4.Algorithm Gossip: 三色棋 7 5.Algorithm Gossip: 老鼠走迷官(一) 9 6.Algorithm Gossip: 老鼠走迷官(二) 11 7.Algorithm Gossip: 骑士走棋盘 ...

    开源框架 Spring Gossip

    IntroductionInterceptor DelegatingIntroductionInterceptor Autoproxing 自动代理可以让您不用为每一个要被 Advised 的 Target 手动定义代理物件,透过 Bean 名称或是 Pointcut 的比对,自动为...

    学习spring的很好的参考资料——Spring Gossip

    此为很有人气的Gossip的学习笔记,里面深入浅出的讲解了关于spring框架的知识与学习心得,是理解spring的不可多得的好资料。 此资料为html形式,每个知识点单独列为一张html页面,阅读很方便,不需要pdf格式下的阅读...

    R-gossip:分布式负载均衡效率优化算法.pdf

    R-gossip算法通过在分布式系统的集群代理节点上设置移位寄存器,优化了传统gossip算法的收敛速度和负载均衡效率。这一改进为分布式系统提供了一种有效的负载均衡优化方案,对分布式系统设计和性能优化具有重要的指导...

    Algorithm.rar_Algorithm Gossip_gossip_gossip algorithm_gossip算法

    2.Algorithm Gossip: 费式数列 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇 9....

    camel-gossip:骆驼八卦

    草稿用法: from("gossip://&lt;bound&gt;:&lt;port&gt;/?peers=&lt;listOfPeers&gt;&routeIds=&lt;listOfRouteIdsToControl&gt;").to("controlbus:route");listOfRouteIdsToControl在此节点被提升/降级时启动/停止。 当您在需要故障转移...

    gossip:Gossip协议的Go实现

    Gossip协议的Go实现。 概述 该软件包提供了最终一致的内存中数据存储的实现。 数据存储值使用推挽式八卦协议进行交换。 // Create a gossiper g := NewGossiper("&lt;ip&gt;:&lt;port&gt;", "&lt;unique&gt;", "&lt;peer&gt;") // Add ...

    R-gossip:分布式负载均衡效率优化算法

    针对在分布式一致性系统中常用的gossip算法负载均衡效率较低的问题,本文在概率gossip算法(probabilistic gossip algorithm)的基础上,设计了一种寄存器gossip算法(register gossip algorithm,下文简称R-gossip...

    99乘法表java源码-gossip:一个javalisp解析器

    gossip - yet another lisp interpreter gossip是一个lisp解释器, 语法借鉴了scheme以及common lisp, 此项目的主要目的是学习。 安装 下载源码 打包: mvn package 运行方式: java -jar your_gossip_home/gossip-1.0-...

    spring学习资料大全

    4. **Spring Gossip_Simp**: 这个文件名可能是某种简化版的Spring教程,可能包含易于理解的Spring基础知识和常见概念,例如: - **XML配置**:介绍如何通过XML文件配置Spring Bean。 - **注解驱动开发**:使用...

    nodejs_gossip:nodejs八卦协议实现

    nodejs_八卦 nodejs八卦协议实现 nodejs 八卦.js 连接到 localhost:8080 在 chrome 中查看网络状态 控制台命令: 重启重置对等体颜色 css_color 建立网络的节点 断网示例 重建网络

    CSC-582-3-W15-GOSSIP:分布式八卦算法

    分布式八卦算法,通常被称为Gossip协议,是一种在分布式系统中高效传播和同步信息的方法。它在许多场景下被广泛使用,比如在大规模的数据库复制、负载均衡、故障检测以及网络中的消息传递等。这种算法的设计灵感来源...

    gossip:一个在线用户界面,可以有效地创作和交付令人敬畏的和内容丰富的演示文稿。 :rocket:

    因此,我将软件命名为Gossip来构建一个工具,该工具使用户可以更有效,更方便地制作和传达故事。 使您的下一个演示文稿不是演示文稿。 入门 有一个可以帮助您使用Gossip创建和交付演示文稿所需的所有技术。 还有...

    p2p-gossip:用于请求工件的 p2p 八卦协议

    例如,./ ./gossip -p --verbose 实例化二进制后续时间以使用get参数接收资源。 例如,./ ./gossip get cats.jpg 运行测试 运行单元测试不需要任何设置。 go test ./... 包装说明 ID ID 包提供了生成唯一的随机 ...

    gossip:通过网络套接字发送和接收消息的基准

    标题中的“gossip”通常指的是一个分布式通信协议或库,用于节点间的高效、可靠的消息传递。在这种场景下,它可能是用JavaScript实现的一个轻量级、去中心化的通信框架,允许程序通过网络套接字(network sockets)...

    springcloud部署redis集群

    集群中的节点之间通过Gossip协议进行通信,用于发现和管理节点状态。 在部署Redis集群前,你需要准备至少三个物理或虚拟机,因为Redis集群至少需要三个主节点来保证数据的可用性。每个节点都需要安装并启动Redis...

Global site tag (gtag.js) - Google Analytics