Created
November 27, 2013 06:26
-
-
Save javajack/7671468 to your computer and use it in GitHub Desktop.
http://blog.nemccarthy.me/?p=272 With Akka 2.2-RC1 coming out last night I decided to upgrade. There are a few changes that make DI with Akka in Java much easier. Previously (Akka 2.1) I was using the UntypedActorFactory approach, however in 2.2 this seems that these methods have been deprecated in favor of the Creator approach. Trying to dig ar…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Component | |
@org.springframework.context.annotation.Scope("prototype") | |
public class EmailServiceActor extends UntypedActor { | |
@Override | |
public void onReceive(Object message) throws Exception { | |
//Do actor stuff... | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import akka.actor.Actor; | |
import akka.actor.IndirectActorProducer; | |
import email.ApplicationContextProvider; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* A class to create a new Actor Instance from a Spring Bean with PROTOTYPE scope | |
* Usage : | |
* akka.actorOf(Props.create(SpringConfiguredActor.class, EmailServiceActor.class, "myActor").withRouter(new SmallestMailboxRouter(3)), "myActorService"); | |
* User: Nathan | |
*/ | |
// Trick 1 – Getting a Bean from Spring App Context: | |
public class SpringConfiguredActor implements IndirectActorProducer { | |
private static final Logger LOG = LoggerFactory.getLogger(SpringDIActor.class); | |
private String beanId; | |
private Class<? extends Actor> type; | |
/** | |
* Get an Actor bean instance of bean #type with ID=#beanName | |
* @param type | |
* @param beanName | |
*/ | |
public SpringConfiguredActor(Class<? extends Actor> type, String beanName) { | |
this.beanId = beanName; | |
this.type = type; | |
} | |
/** | |
* Get an instance bean of #type from the App Context - By Type wiring | |
* @param type | |
*/ | |
public SpringConfiguredActor(Class<? extends Actor> type) { | |
this.type = type; | |
} | |
/** | |
* This factory method must produce a fresh actor instance upon each | |
* invocation. <b>It is not permitted to return the same instance more than | |
* once.</b> | |
*/ | |
@Override | |
public Actor produce() { | |
if (beanId != null) { | |
//By Name wiring; | |
return (Actor) ApplicationContextProvider.getApplicationContext().getBean(beanId); | |
} | |
//By Type wiring; | |
return (Actor) ApplicationContextProvider.getApplicationContext().getBean(type); | |
} | |
/** | |
* This method is used by [[Props]] to determine the type of actor which will | |
* be created. This means that an instance of this `IndirectActorProducer` | |
* will be created in order to call this method during any call to | |
* [[Props#actorClass]]; it should be noted that such calls may | |
* performed during actor set-up before the actual actor’s instantiation, and | |
* that the instance created for calling `actorClass` is not necessarily reused | |
* later to produce the actor. | |
*/ | |
@Override | |
public Class<? extends Actor> actorClass() { | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import akka.actor.Actor; | |
import akka.actor.IndirectActorProducer; | |
import email.ApplicationContextProvider; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* Create a new instance of the Actor and then autowire its fields by passing it to the Spring App Context | |
* //Expanded this to take an instance and just autowire it. | |
Usage: | |
akka.actorOf(Props.create(SpringDIActor.class, MyActor.class) | |
.withRouter(new SmallestMailboxRouter(3)), "myActorService"); | |
You can create a Spring wired actor from within another actor (in fact you should to take advantage of akka’s actor hierarchies). To do this from within an actor its the same call; | |
e.g. in MyActor class you could have; | |
private ActorRef mySubWorker = getContext().actorOf(Props.create(SpringConfiguredActor.class, MyActor.class, "myNestedActor") | |
.withRouter(new SmallestMailboxRouter(3)), "myNestedActorService"); | |
* User: Nathan | |
*/ | |
// Trick 2 – Manually create the instance and autowire it by passing it to the Spring Application Context | |
public class SpringDIActor implements IndirectActorProducer { | |
private static final Logger LOG = LoggerFactory.getLogger(SpringDIActor.class); | |
private Class<? extends Actor> type; | |
private Actor actorInstance = null; | |
public SpringDIActor(Class<? extends Actor> type) { | |
this.type = type; | |
} | |
public SpringDIActor(Actor actorInstance) { | |
this.actorInstance = actorInstance; | |
} | |
/** | |
* This factory method must produce a fresh actor instance upon each | |
* invocation. <b>It is not permitted to return the same instance more than | |
* once.</b> | |
*/ | |
@Override | |
public Actor produce() { | |
Actor newActor = actorInstance; | |
actorInstance = null; | |
if (newActor == null) { | |
try { | |
newActor = type.newInstance(); | |
} catch (InstantiationException | IllegalAccessException e) { | |
LOG.error("Unable to create actor of type:{}", type, e); | |
} | |
} | |
ApplicationContextProvider.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(newActor); | |
return newActor; | |
} | |
/** | |
* This method is used by [[Props]] to determine the type of actor which will | |
* be created. This means that an instance of this `IndirectActorProducer` | |
* will be created in order to call this method during any call to | |
* [[Props#actorClass]]; it should be noted that such calls may | |
* performed during actor set-up before the actual actor’s instantiation, and | |
* that the instance created for calling `actorClass` is not necessarily reused | |
* later to produce the actor. | |
*/ | |
@Override | |
public Class<? extends Actor> actorClass() { | |
return type; | |
// ParameterizedType parameterizedType = (ParameterizedType)getClass().getGenericSuperclass(); | |
// return (Class) parameterizedType.getActualTypeArguments()[0]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment