+act #17576 Support serializer with string manifest
* useful when evolution is needed, e.g. Akka Persistence * docs, comments, cluster-metrics and cluster-tools serializers
This commit is contained in:
parent
aeb2302c2f
commit
740f006a38
21 changed files with 605 additions and 93 deletions
|
|
@ -26,7 +26,7 @@ import akka.serialization.JavaSerializer.CurrentSystem
|
|||
* load classes using reflection.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <b>Be sure to always use the PropertyManager for loading classes!</b> This is necessary to
|
||||
* <b>Be sure to always use the [[akka.actor.DynamicAccess]] for loading classes!</b> This is necessary to
|
||||
* avoid strange match errors and inequalities which arise from different class loaders loading
|
||||
* the same class.
|
||||
*/
|
||||
|
|
@ -65,6 +65,74 @@ trait Serializer {
|
|||
final def fromBinary(bytes: Array[Byte], clazz: Class[_]): AnyRef = fromBinary(bytes, Option(clazz))
|
||||
}
|
||||
|
||||
/**
|
||||
* A Serializer represents a bimap between an object and an array of bytes representing that object.
|
||||
*
|
||||
* For serialization of data that need to evolve over time the `SerializerWithStringManifest` is recommended instead
|
||||
* of [[Serializer]] because the manifest (type hint) is a `String` instead of a `Class`. That means
|
||||
* that the class can be moved/removed and the serializer can still deserialize old data by matching
|
||||
* on the `String`. This is especially useful for Akka Persistence.
|
||||
*
|
||||
* The manifest string can also encode a version number that can be used in [[#fromBinary]] to
|
||||
* deserialize in different ways to migrate old data to new domain objects.
|
||||
*
|
||||
* If the data was originally serialized with [[Serializer]] and in a later version of the
|
||||
* system you change to `SerializerWithStringManifest` the manifest string will be the full class name if
|
||||
* you used `includeManifest=true`, otherwise it will be the empty string.
|
||||
*
|
||||
* Serializers are loaded using reflection during [[akka.actor.ActorSystem]]
|
||||
* start-up, where two constructors are tried in order:
|
||||
*
|
||||
* <ul>
|
||||
* <li>taking exactly one argument of type [[akka.actor.ExtendedActorSystem]];
|
||||
* this should be the preferred one because all reflective loading of classes
|
||||
* during deserialization should use ExtendedActorSystem.dynamicAccess (see
|
||||
* [[akka.actor.DynamicAccess]]), and</li>
|
||||
* <li>without arguments, which is only an option if the serializer does not
|
||||
* load classes using reflection.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <b>Be sure to always use the [[akka.actor.DynamicAccess]] for loading classes!</b> This is necessary to
|
||||
* avoid strange match errors and inequalities which arise from different class loaders loading
|
||||
* the same class.
|
||||
*/
|
||||
abstract class SerializerWithStringManifest extends Serializer {
|
||||
|
||||
/**
|
||||
* Completely unique value to identify this implementation of Serializer, used to optimize network traffic.
|
||||
* Values from 0 to 16 are reserved for Akka internal usage.
|
||||
*/
|
||||
def identifier: Int
|
||||
|
||||
final override def includeManifest: Boolean = true
|
||||
|
||||
/**
|
||||
* Return the manifest (type hint) that will be provided in the fromBinary method.
|
||||
* Use `""` if manifest is not needed.
|
||||
*/
|
||||
def manifest(o: AnyRef): String
|
||||
|
||||
/**
|
||||
* Serializes the given object into an Array of Byte
|
||||
*/
|
||||
def toBinary(o: AnyRef): Array[Byte]
|
||||
|
||||
/**
|
||||
* Produces an object from an array of bytes, with an optional type-hint;
|
||||
* the class should be loaded using ActorSystem.dynamicAccess.
|
||||
*/
|
||||
def fromBinary(bytes: Array[Byte], manifest: String): AnyRef
|
||||
|
||||
final def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = {
|
||||
val manifestString = manifest match {
|
||||
case Some(c) ⇒ c.getName
|
||||
case None ⇒ ""
|
||||
}
|
||||
fromBinary(bytes, manifestString)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base serializer trait with serialization identifiers configuration contract,
|
||||
* when globally unique serialization identifier is configured in the `reference.conf`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue