Merge pull request #1933 from akka/wip-3764-props-docs-∂π
clean up docs and deprecation around how to create Props
This commit is contained in:
commit
453815c073
17 changed files with 99 additions and 244 deletions
|
|
@ -11,14 +11,17 @@ import static akka.pattern.Patterns.pipe;
|
|||
import static akka.pattern.Patterns.gracefulStop;
|
||||
//#import-gracefulStop
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import akka.testkit.AkkaJUnitActorSystemResource;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
//#import-gracefulStop
|
||||
import scala.concurrent.Await;
|
||||
//#import-ask
|
||||
|
|
@ -119,43 +122,6 @@ public class UntypedActorDocTest {
|
|||
}
|
||||
//#parametric-creator
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void createPropsDeprecated() {
|
||||
//#creating-props-deprecated
|
||||
// DEPRECATED: encourages to close over enclosing class
|
||||
final Props props1 = new Props(new UntypedActorFactory() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public UntypedActor create() throws Exception {
|
||||
return new MyUntypedActor();
|
||||
}
|
||||
});
|
||||
|
||||
// DEPRECATED: encourages to close over enclosing class
|
||||
final Props props2 = new Props().withCreator(new UntypedActorFactory() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public UntypedActor create() throws Exception {
|
||||
return new MyUntypedActor();
|
||||
}
|
||||
});
|
||||
|
||||
// these are DEPRECATED due to duplicate functionality with Props.create()
|
||||
final Props props3 = new Props(MyUntypedActor.class);
|
||||
final Props props4 = new Props().withCreator(MyUntypedActor.class);
|
||||
//#creating-props-deprecated
|
||||
new JavaTestKit(system) {
|
||||
{
|
||||
for (Props props : new Props[] { props1, props2, props3, props4 }) {
|
||||
final ActorRef a = system.actorOf(props);
|
||||
a.tell("hello", getRef());
|
||||
expectMsgEquals("hello");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemActorOf() {
|
||||
//#system-actorOf
|
||||
|
|
@ -538,8 +504,15 @@ public class UntypedActorDocTest {
|
|||
* @return a Props for creating this actor, which can then be further configured
|
||||
* (e.g. calling `.withDispatcher()` on it)
|
||||
*/
|
||||
public static Props props(int magicNumber) {
|
||||
return Props.create(DemoActor.class, magicNumber);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -65,52 +65,22 @@ example of a parametric factory could be:
|
|||
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java#parametric-creator
|
||||
|
||||
Deprecated Variants
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
.. note::
|
||||
|
||||
Up to Akka 2.1 there were also the following possibilities (which are retained
|
||||
for a migration period):
|
||||
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java#import-untypedActor
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java#creating-props-deprecated
|
||||
|
||||
The last two are deprecated because their functionality is available in full
|
||||
through :meth:`Props.create()`.
|
||||
|
||||
The first two are deprecated because the resulting :class:`UntypedActorFactory`
|
||||
is typically a local class which means that it implicitly carries a reference
|
||||
to the enclosing class. This can easily make the resulting :class:`Props`
|
||||
non-serializable, e.g. when the enclosing class is an :class:`Actor`. Akka
|
||||
advocates location transparency, meaning that an application written with
|
||||
actors should just work when it is deployed over multiple network nodes, and
|
||||
non-serializable actor factories would break this principle. In case indirect
|
||||
actor creation is needed—for example when using dependency injection—there is
|
||||
the possibility to use an :class:`IndirectActorProducer` as described below.
|
||||
|
||||
There were two use-cases for these methods: passing constructor arguments to
|
||||
the actor—which is solved by the newly introduced :meth:`Props.create()` method
|
||||
above—and creating actors “on the spot” as anonymous classes. The latter should
|
||||
be solved by making these actors named inner classes instead (if they are not
|
||||
``static`` then the enclosing instance’s ``this`` reference needs to be passed
|
||||
as the first argument).
|
||||
|
||||
.. warning::
|
||||
|
||||
Declaring one actor within another is very dangerous and breaks actor
|
||||
encapsulation unless the nested actor is a static inner class. Never pass an
|
||||
actor’s ``this`` reference into :class:`Props`!
|
||||
In order for mailbox requirements—like using a deque-based mailbox for actors
|
||||
using the stash—to be picked up, the actor type needs to be known before
|
||||
creating it, which is what the :class:`Creator` type argument allows.
|
||||
Therefore make sure to use the specific type for your actors wherever
|
||||
possible.
|
||||
|
||||
Recommended Practices
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It is a good idea to provide static factory methods on the
|
||||
:class:`UntypedActor` which help keeping the creation of suitable
|
||||
:class:`Props` as close to the actor definition as possible, thus containing
|
||||
the gap in type-safety introduced by reflective instantiation within a single
|
||||
class instead of spreading it out across a whole code-base. This helps
|
||||
especially when refactoring the actor’s constructor signature at a later point,
|
||||
where compiler checks will allow this modification to be done with greater
|
||||
confidence than without.
|
||||
:class:`Props` as close to the actor definition as possible. This also allows
|
||||
usage of the :class:`Creator`-based methods which statically verify that the
|
||||
used constructor actually exists instead relying only on a runtime check.
|
||||
|
||||
.. includecode:: code/docs/actor/UntypedActorDocTest.java#props-factory
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue