Introduksjon til Kryo

1. Oversikt

Kryo er et Java-serialiseringsrammeverk med fokus på hastighet, effektivitet og et brukervennlig API.

I denne artikkelen vil vi utforske hovedtrekkene i Kryo-rammeverket og implementere eksempler for å vise evnene.

2. Maven avhengighet

Det første vi må gjøre er å legge til kryo avhengighet til vår pom.xml:

 com.esotericsoftware kryo 4.0.1 

Den siste versjonen av denne gjenstanden finner du på Maven Central.

3. Kryo Basics

La oss starte med å se på hvordan Kryo fungerer, og hvordan vi kan serieisere og deserialisere objekter med den.

3.1. Introduksjon

Rammeverket gir Kryo klasse som hovedinngangspunkt for all funksjonalitet.

Denne klassen orkestrerer serieiseringsprosessen og tilordner klassene til Serializer tilfeller som håndterer detaljene for å konvertere et objekts graf til en byte-representasjon.

Når byte er klare, blir de skrevet til en strøm ved hjelp av en Produksjon gjenstand. På denne måten kan de lagres i en fil, en database eller overføres over nettverket.

Senere, når objektet er nødvendig, an Inngang forekomst brukes til å lese disse byte og dekode dem til Java-objekter.

3.2. Serialisere objekter

Før vi dykker inn i eksempler, la oss først lage en verktøymetode for å initialisere noen variabler vi vil bruke for hver testtilfelle i denne artikkelen:

@Før offentlig ugyldig init () {kryo = ny Kryo (); utgang = ny utgang (ny FileOutputStream ("file.dat")); input = new Input (new FileInputStream ("file.dat")); }

Nå kan vi se hvor lett det er å skrive og lese et objekt ved hjelp av Kryo:

@Test public void givenObject_whenSerializing_thenReadCorrectly () {Object someObject = "Noen streng"; kryo.writeClassAndObject (output, someObject); output.close (); Objekter theObject = kryo.readClassAndObject (input); input.close (); assertEquals (objektet, "Noen streng"); }

Legg merke til samtalen til Lukk() metode. Dette er nødvendig siden Produksjon og Inngang klasser arver fra OutputStream og InputStream henholdsvis.

Serialisering av flere objekter er like grei:

@Test offentlig ugyldighet gittObjects_whenSerializing_thenReadCorrectly () {String someString = "Flere objekter"; Date someDate = new Date (915170400000L); kryo.writeObject (output, someString); kryo.writeObject (output, someDate); output.close (); String readString = kryo.readObject (input, String.class); Date readDate = kryo.readObject (input, Date.class); input.close (); assertEquals (readString, "Flere objekter"); assertEquals (readDate.getTime (), 915170400000L); }

Legg merke til at vi sender riktig klasse til readObject () metode, gjør dette koden vår kastfri.

4. Serializers

I denne delen viser vi hvilken Serializers er allerede tilgjengelige, og så lager vi våre egne.

4.1. Standard Serializers

Når Kryo serierer et objekt, oppretter det en forekomst av en tidligere registrert Serializer klasse for å gjøre konverteringen til byte. Disse kalles standardserialiserer og kan brukes uten noe oppsett fra vår side.

Biblioteket har allerede flere slike serialisatorer som behandler primitiver, lister, kart, enums osv. Hvis det ikke finnes noen serializer for en gitt klasse, så FieldSerializer brukes, som kan håndtere nesten alle typer gjenstander.

La oss se hvordan dette ser ut. La oss først lage en Person klasse:

offentlig klasse Person {private String name = "John Doe"; privat alder = 18; privat dato fødselsdato = ny dato (933191282821L); // standardkonstruktører, getters og setters}

La oss nå skrive et objekt fra denne klassen og deretter lese det tilbake:

@Test offentlig ugyldighet gittPerson_whenSerializing_thenReadCorrectly () {Person person = new Person (); kryo.writeObject (utgang, person); output.close (); Person readPerson = kryo.readObject (input, Person.class); input.close (); assertEquals (readPerson.getName (), "John Doe"); }

Legg merke til at vi ikke trengte å spesifisere noe for å serieisere en Person objekt siden a FieldSerializer blir opprettet automatisk for oss.

4.2. Egendefinerte Serializers

Hvis vi trenger mer kontroll over serieiseringsprosessen, har vi to alternativer; vi kan skrive våre egne Serializer klasse og registrere den med Kryo eller la klassen håndtere serialiseringen av seg selv.

For å demonstrere det første alternativet, la oss lage en klasse som utvides Serializer:

offentlig klasse PersonSerializer utvider Serializer {public void write (Kryo kryo, Output output, Person object) {output.writeString (object.getName ()); output.writeLong (object.getBirthDate (). getTime ()); } offentlig person lest (Kryo kryo, Input input, Class type) {Person person = new Person (); person.setName (input.readString ()); lang fødselsdato = input.readLong (); person.setBirthDate (ny dato (fødselsdato)); person.setAge (CalcAge (fødselsdato)); retur person; } private int calcAAge (long birthDate) {// Noe tilpasset logikk returnerer 18; }}

La oss nå prøve:

@Test offentlig ugyldig givenPerson_whenUsingCustomSerializer_thenReadCorrectly () {Person person = new Person (); person.setAge (0); kryo.register (Person.class, ny PersonSerializer ()); kryo.writeObject (utdata, person); output.close (); Person readPerson = kryo.readObject (input, Person.class); input.close (); assertEquals (readPerson.getName (), "John Doe"); assertEquals (readPerson.getAge (), 18); }

Legg merke til at alder feltet er lik 18, selv om vi tidligere satte det til 0.

Vi kan også bruke @DefaultSerializer kommentar for å gi Kryo beskjed om at vi vil bruke PersonSerializer hver gang den trenger å håndtere en Person gjenstand. Dette bidrar til å unngå samtalen til registrere() metode:

@DefaultSerializer (PersonSerializer.class) offentlig klasse Person implementerer KryoSerializable {// ...}

For det andre alternativet, la oss endre vår Person klasse for å utvide KryoSerializable grensesnitt:

offentlig klasse Person implementerer KryoSerializable {// ... public void write (Kryo kryo, Output output) {output.writeString (name); // ...} public void read (Kryo kryo, Input input) {name = input.readString (); // ...}}

Siden prøvesaken for dette alternativet er lik en tidligere, er ikke inkludert her. Du kan imidlertid finne den i kildekoden for denne artikkelen.

4.3. Java Serializer

I sporadiske tilfeller vil Kryo ikke være i stand til å serieisere en klasse. Hvis dette skjer, og det ikke er et alternativ å skrive en tilpasset serializer, kan vi bruke standard Java-serialiseringsmekanismen ved hjelp av en JavaSerializer. Dette krever at klassen implementerer Serialiserbar grensesnitt som vanlig.

Her er et eksempel som bruker den nevnte serialisereren:

offentlig klasse ComplexObject implementerer Serializable {private String name = "Bael"; // standard getters og setters}
@Test offentlig ugyldig gittJavaSerializable_whenSerializing_thenReadCorrectly () {ComplexClass complexObject = ny ComplexClass (); kryo.register (ComplexClass.class, ny JavaSerializer ()); kryo.writeObject (output, complexObject); output.close (); ComplexClass readComplexObject = kryo.readObject (inngang, ComplexClass.class); input.close (); assertEquals (readComplexObject.getName (), "Bael"); }

5. Konklusjon

I denne veiledningen utforsket vi de mest bemerkelsesverdige funksjonene i Kryo-biblioteket.

Vi serierte flere enkle objekter og brukte FieldSerializer klasse for å håndtere en tilpasset en. Vi opprettet også en tilpasset serialisering og demonstrerte hvordan vi kan tilbakebetale standard Java-serialiseringsmekanismen om nødvendig.

Som alltid kan du finne den fullstendige kildekoden for denne artikkelen på Github.


$config[zx-auto] not found$config[zx-overlay] not found