akka在spring下的测试例子

1、测试目标:证实Akka确保Actor的每个实例都运行在自己的轻量级线程里,并拥有自己的队列,保证先进先出的处理每一条消息。

2、akka中actor既是发射器又是接收器,发消息和收消息时必经过自己的onReceive方法。

3、如果使用从spring获取的同一实例测试,得出每个actor实例是自包含一个队列的,发和收的顺序一致。

AnnotationConfigApplicationContext ctx =
	          new AnnotationConfigApplicationContext();
	        ctx.scan("com.anyvape.common.akka");
	        ctx.refresh();

	        // get hold of the actor system
	        ActorSystem system = ctx.getBean(ActorSystem.class);
	        // use the Spring Extension to create props for a named actor bean
	        ActorRef greeter = system.actorOf(
	        		CountingProvider.get(system).props("CountingActor"), "counter");

	        ActorRef greetPrinter = system.actorOf(
	        		CountingProvider.get(system).props("GreetPrinter"), "greetPrinter");

	    	for(int i=0;i<100;i++){

	        	greeter.tell(new Greeting(String.valueOf(i)), greetPrinter);
	        }

4、同一actor类的多个actor实例向同一actor实例发消息测试。测试时在接受方加一断点,等到发送方发送完毕,打开断点,发现接受方打印顺序和发送顺序一致。

AnnotationConfigApplicationContext ctx =
	          new AnnotationConfigApplicationContext();
	        ctx.scan("com.anyvape.common.akka");
	        ctx.refresh();

	        // get hold of the actor system
	        ActorSystem system = ctx.getBean(ActorSystem.class);
	        // use the Spring Extension to create props for a named actor bean
	        ActorRef greeter = system.actorOf(
	        		CountingProvider.get(system).props("CountingActor"), "counter");

	        ActorRef greetPrinter = system.actorOf(
	        		CountingProvider.get(system).props("GreetPrinter"), "greetPrinter");

	    	for(int i=0;i<100;i++){
	    		greeter = system.actorOf(
		        		CountingProvider.get(system).props("CountingActor"), "counter".concat(String.valueOf(i)));
	        	greeter.tell(new Greeting(String.valueOf(i)), greetPrinter);
	        }

5、代码

spring的注解配置类

import akka.actor.ActorSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static com.anyvape.common.akka.producer.CountingActorFactory.CountingProvider;

/**
 * The application configuration.
 */
@Configuration
class AppConfiguration {

  // the application context is needed to initialize the Akka Spring Extension
  @Autowired
  private ApplicationContext applicationContext;

  /**
   * Actor system singleton for this application.
   */
  @Bean
  public ActorSystem actorSystem() {
    ActorSystem system = ActorSystem.create("AkkaJavaSpring");
    // initialize the application context in the Akka Spring Extension
    CountingProvider.get(system).initialize(applicationContext);
    return system;
  }
}

从spring管理上下文获取actor的代理类

import akka.actor.Actor;
import akka.actor.IndirectActorProducer;
import org.springframework.context.ApplicationContext;

/**
 * 一个代理类,从spring上下文获取对象,实例必须实现生产actor的接口方法和定义生产类类型的接口方法
 * An actor producer that lets Spring create the Actor instances.
 */
public class ActorProducer implements IndirectActorProducer {
  final ApplicationContext applicationContext;
  final String actorBeanName;

  public ActorProducer(ApplicationContext applicationContext,
                             String actorBeanName) {
    this.applicationContext = applicationContext;
    this.actorBeanName = actorBeanName;
  }

  @Override
  public Actor produce() {
    return (Actor) applicationContext.getBean(actorBeanName);
  }

  @Override
  public Class<? extends Actor> actorClass() {
    return (Class<? extends Actor>) applicationContext.getType(actorBeanName);
  }
}

工厂类,使用上面的代理生成actor

import akka.actor.AbstractExtensionId;
import akka.actor.ExtendedActorSystem;
import akka.actor.Extension;
import akka.actor.Props;
import org.springframework.context.ApplicationContext;

/**
 * 调用ActorProducer创建actor
 * An Akka Extension to provide access to Spring managed Actor Beans.
 */
public class CountingActorFactory extends
  AbstractExtensionId<CountingActorFactory.SpringExt> {

  /**
   * The identifier used to access the SpringExtension.
   */
  public static CountingActorFactory CountingProvider = new CountingActorFactory();

  /**
   * Is used by Akka to instantiate the Extension identified by this
   * ExtensionId, internal use only.
   */
  @Override
  public SpringExt createExtension(ExtendedActorSystem system) {
    return new SpringExt();
  }

  /**
   * The Extension implementation.
   */
  public static class SpringExt implements Extension {
    private volatile ApplicationContext applicationContext;

    /**
     * Used to initialize the Spring application context for the extension.
     * @param applicationContext
     */
    public void initialize(ApplicationContext applicationContext) {
      this.applicationContext = applicationContext;
    }

    /**
     * Create a Props for the specified actorBeanName using the
     * SpringActorProducer class.
     *
     * @param actorBeanName  The name of the actor bean to create Props for
     * @return a Props that will create the named actor bean using Spring
     */
    public Props props(String actorBeanName) {
      return Props.create(ActorProducer.class,
        applicationContext, actorBeanName);
    }
  }
}

角色1

import java.util.Random;
import akka.actor.UntypedActor;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.anyvape.common.akka.service.CountingService;

/**
 * 异步统计用户对这个关键词的使用频率
 *
 * @note The scope here is prototype since we want to create a new actor
 * instance for use of this bean.
 */
@Component("CountingActor")
public class CountingActor extends UntypedActor {

  public static class Count {}
  public static class Get {}
  @Autowired
  CountingService countingService;

  private int count = 0;

  @Override
  public void onReceive(Object message) throws Exception {
    if (message instanceof Count) {
      count = countingService.increment(count);
      System.out.println("--------"+count);
      //Thread.sleep(new Random().nextInt(400) + 1);
    } else if (message instanceof Get) {
      getSender().tell(count, getSelf());
    } else {
      unhandled(message);
    }
  }
}

角色2

import java.util.Random;

import com.anyvape.common.akka.Hello2.Greeting;

import akka.actor.UntypedActor;

public class GreetPrinter extends UntypedActor {
    public void onReceive(Object message) {
        if (message instanceof Greeting)
            System.out.println("-------------re:"+((Greeting) message).message);
        	try {
				Thread.sleep(new Random().nextInt(5*1000) + 1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	getSender().tell(new com.anyvape.common.akka.Hello2.End(((Greeting) message).message), getSelf());
    }
}
时间: 2024-10-05 10:11:46

akka在spring下的测试例子的相关文章

Spring框架下Junit测试

Spring框架下Junit测试 一.设置 1.1 目录 设置源码目录和测试目录,这样在设置产生测试方法时,会统一放到一个目录,如果没有设置测试目录,则不会产生测试代码. 1.2 增加配置文件 Resources目录下创建配置文件. 1.3 引入包和配置文件 import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframewo

Spring与junit测试

1.我们知道无论在J2SE还是android中都有junit测试,利用junit能够帮助方便测试代码.在之前的博客中我也写了一些J2SE的一些junit测试例子,今天对于Spring中junit小小的讨论一下. 这个Spring测试需要的jar包:      spring-test-3.2.0.RELEASE.jar 2.Spring和Junit的关系图 左边的采用传统的方式,即一般的J2SE的方式测试代码,这种情况会有些问题: (1).每一个测试都要启动Spring, (2).这种情况下,是测

Spring简单的小例子SpringDemo,用于初略理解什么是Spring以及JavaBean的一些概念

一.开发前的准备 两个开发包spring-framework-3.1.1.RELEASE-with-docs.zip和commons-logging-1.2-bin.zip,将它们解压,然后把Spring开发包下dist目录的所有包和commons-logging包下的commons-logging-1.1.1.jar复制到名为Spring3.1.1的文件夹下.那么Spring开发所需要的包就组织好了. 二.建立项目,导入包 在项目节点上右键,Build Path/ADD Libraries/U

【译】Spring 4 Hello World例子

前言 译文链接:http://websystique.com/spring/spring-4-hello-world-example-annotation-tutorial-full-example/ 这个教程将展示一个基于Spring注解配置的Spring 4 Hello world例子,解释Spring 4的基本概念和使用方法. 同样也会提供基于XML配置的示例作为两者的一个比较,我们将创建一个基于maven工程,使用spring版本为4.0.6. 涉及的相关技术及开发工具 Spring 4

spring下配置dbcp,c3p0,proxool

不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spring中,数据连接是通过数据源获得的.在以往的应用中,数据源一般是Web应用服务器提供的.在Spring中,你不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,此外,你还可以通过代码的方式创建一个数据源,以便进行无依赖的单元测试 配置一个数据源     Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0.可以在Spring配置文件中利用这两者中任何

为初学者写三层,三层的搭建和测试例子

三层搭建过程   第一步打开vs,然后点击新建—---项目—----其它项目类型-------空白解决方案.如下图! (备注右上角是你建立的版本是3.5 的还是2.0的,这里选择的是3.5的) 注意1:名称可以重命名,这个地方我命名的是Test_Example. 注意2:存放位置自己选择一个新路径,便于以后的查找.   然后点击确认按钮提交: 这样出现一个下图的空白解决方案.   第二步:我们建立一个数据访问层:首先如上图中选中空白解决方案,然后右键----添加-----  然后选择新建项目--

Spring MVC参数化测试 - Junit Parameterized

参考文章:Spring MVC全注解配置 - 无web.xml 单元测试的目的,简单来说就是在我们增加或者改动一些代码以后对所有逻辑的一个检测,尤其是在我们后期修改后(不论是增加新功能,修改bug),都可以做到重新测试的工作.以减少我们在发布的时候出现更过甚至是出现之前解决了的问题再次重现. Spring MVC的测试往往看似比较复杂.其实他的不同在于,他需要一个ServletContext来模拟我们的请求和响应.但是Spring也针对Spring MVC 提供了请求和响应的模拟测试接口,以方便

spring下应用@Resource, @Autowired 和 @Inject注解进行依赖注入的差

代码: 为了探寻  '@Resource', '@Autowired', 和'@Inject'如何解决依赖注入中的问题,我创建了一个"Party"接口,和它的两个实现类"Person","Organization".这样我就可以在注入Bean的时候不必使用具体类型(指使用接口类型即可).这样做也方便我研究当一个接口有多个实现类与之匹配的时候Spring是如何解决依赖注入的不确定性的. public interface Party {} packa

thrift windows vs2013测试例子

首先需要编译thrift的compiler 源代码目录在: \thrift-master\compiler\cpp 原来是vs2010的功能,用vs2013打开之后会提示升级,因为这只是一个工具,所以不需要升级,直接编译得到需要的exe 编译之后得到一个thrift.exe,这个工具可以把中间代码生成对应的目标代码 生成需要的测试代码 在thrift.exe的目录中新建一个记事本,粘贴如下内容保存,之后把文件名改成student.thrift: <span style="font-size