【发布时间】:2016-04-13 08:44:11
【问题描述】:
在我的项目中,我使用Lightbend activator template 作为代码库。它工作完美,但示例中的 Actor 不是使用参数创建的。
我需要创建一个新的 Actor 并在构造过程中向它传递一个参数,例如:
getContext().actorOf(SpringExtProvider.get(actorSystem).props("ControllerActor",type), "controller_" + type)
在这个用例中,控制器需要能够使用 props 参数 type 创建,该参数用于键入(显然)控制器。每个 Actor 都经过专门设计,可根据其类型处理和控制特定的对象王。
但是我不能在 props 方法中添加一个新参数来传递这个参数。它不工作。
这是我的代码:
SpringExtension.java
package com.orange.spectre.core.akka.configuration;
import akka.actor.AbstractExtensionId;
import akka.actor.ExtendedActorSystem;
import akka.actor.Extension;
import akka.actor.Props;
import com.orange.spectre.core.config.SpringActorProducer;
import org.springframework.context.ApplicationContext;
/**
* Created by Hervé Darritchon on 04/04/2016.
* <p>
* An Akka Extension to provide access to Spring managed Actor Beans.
*/
public class SpringExtension extends AbstractExtensionId<SpringExtension.SpringExt> {
/**
* The identifier used to access the SpringExtension.
*/
public static SpringExtension SpringExtProvider = new SpringExtension();
/**
* 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(SpringActorProducer.class,
applicationContext, actorBeanName);
}
public Props props(String actorBeanName, String type) {
return Props.create(SpringActorProducer.class,
applicationContext, actorBeanName,type);
}
}
}
SpringActorProducer 包 com.orange.spectre.core.config;
import akka.actor.Actor;
import akka.actor.IndirectActorProducer;
import org.springframework.context.ApplicationContext;
/**
* Created by Hervé Darritchon on 21/03/2016.
*/
public class SpringActorProducer implements IndirectActorProducer {
private final ApplicationContext applicationContext;
private final String actorBeanName;
private final String type;
public SpringActorProducer(ApplicationContext applicationContext,
String actorBeanName) {
this.applicationContext = applicationContext;
this.actorBeanName = actorBeanName;
this.type = null;
}
public SpringActorProducer(ApplicationContext applicationContext,
String actorBeanName, String type) {
this.applicationContext = applicationContext;
this.actorBeanName = actorBeanName;
this.type = type;
}
@Override
public Actor produce() {
return (Actor) applicationContext.getBean(actorBeanName);
}
@Override
public Class<? extends Actor> actorClass() {
return (Class<? extends Actor>) applicationContext.getType(actorBeanName);
}
}
我无法创建带有 props 参数的演员,因为基本上可以使用 Akka (Documentation):
public class DemoActor extends UntypedActor {
/**
* Create Props for an actor of this type.
* @param magicNumber The magic number to be passed to this actor’s constructor.
* @return a Props for creating this actor, which can then be further configured
* (e.g. calling `.withDispatcher()` on it)
*/
public static Props props(final int magicNumber) {
return Props.create(new Creator<DemoActor>() {
private static final long serialVersionUID = 1L;
@Override
public DemoActor create() throws Exception {
return new DemoActor(magicNumber);
}
});
}
final int magicNumber;
public DemoActor(int magicNumber) {
this.magicNumber = magicNumber;
}
@Override
public void onReceive(Object msg) {
// some behavior here
}
}
system.actorOf(DemoActor.props(42), "demo");
如果你能帮助我,那就太好了!
谢谢。
【问题讨论】:
-
好问题;希望你的努力会有回报!
-
如果您查看
SpringActorProducer中的代码,构造函数接受类型参数并将其存储在属性中,但是创建actor 的produce方法不使用它。 -
老实说,我不确定您所尝试的是否真的可行。通过将 Actor 创建委托给 Spring 容器,我的经验是您将对象注入 Actor 的方法必须使用 Spring 方法,即
@Autowired。与其将类型注入到你的actor中以告知它可以处理哪种类型的对象,为什么不定义多个不同的actor来处理每个特定的对象类型呢?然后,您将对象路由到要处理的正确参与者