package com.liuxinglanyue.session.redis.share;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.DefaultSerializers;
import de.javakaffee.kryoserializers.ArraysAsListSerializer;
import de.javakaffee.kryoserializers.BitSetSerializer;
import de.javakaffee.kryoserializers.CollectionsEmptyListSerializer;
import de.javakaffee.kryoserializers.CollectionsEmptyMapSerializer;
import de.javakaffee.kryoserializers.CollectionsEmptySetSerializer;
import de.javakaffee.kryoserializers.CollectionsSingletonListSerializer;
import de.javakaffee.kryoserializers.CollectionsSingletonMapSerializer;
import de.javakaffee.kryoserializers.CollectionsSingletonSetSerializer;
import de.javakaffee.kryoserializers.CopyForIterateCollectionSerializer;
import de.javakaffee.kryoserializers.CopyForIterateMapSerializer;
import de.javakaffee.kryoserializers.DateSerializer;
import de.javakaffee.kryoserializers.EnumMapSerializer;
import de.javakaffee.kryoserializers.EnumSetSerializer;
import de.javakaffee.kryoserializers.GregorianCalendarSerializer;
import de.javakaffee.kryoserializers.JdkProxySerializer;
import de.javakaffee.kryoserializers.KryoReflectionFactorySupport;
import de.javakaffee.kryoserializers.RegexSerializer;
import de.javakaffee.kryoserializers.SynchronizedCollectionsSerializer;
import de.javakaffee.kryoserializers.URISerializer;
import de.javakaffee.kryoserializers.UUIDSerializer;
import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer;
/**
* 基于Kryo的序列化 (来自 kryo-serializers)
* @author jiaojianfeng
*
*/
public final class KryoSerializer {
private static final ThreadLocal<Kryo> _threadLocalKryo = new ThreadLocal<Kryo>() {
protected Kryo initialValue() {
Kryo kryo = new KryoReflectionFactorySupport() {
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Serializer<?> getDefaultSerializer(final Class type) {
if (EnumSet.class.isAssignableFrom(type)) {
return new EnumSetSerializer();
}
if (EnumMap.class.isAssignableFrom(type)) {
return new EnumMapSerializer();
}
if (Collection.class.isAssignableFrom(type)) {
return new CopyForIterateCollectionSerializer();
}
if (Map.class.isAssignableFrom(type)) {
return new CopyForIterateMapSerializer();
}
if (Date.class.isAssignableFrom(type)) {
return new DateSerializer(type);
}
// 判断是否是EnhancerByCGLIB
try {
if (type.getName().indexOf("$$EnhancerByCGLIB$$") > 0) {
Method method = Class
.forName("de.javakaffee.kryoserializers.cglib.CGLibProxySerializer")
.getDeclaredMethod("canSerialize", Class.class);
if ((Boolean) method.invoke(null, type)) {
return getSerializer(Class.forName("de.javakaffee.kryoserializers.cglib.CGLibProxySerializer$CGLibProxyMarker"));
}
}
} catch (Throwable thex) {
}
return super.getDefaultSerializer(type);
}
};
kryo.setClassLoader(Thread.currentThread().getContextClassLoader());
kryo.setRegistrationRequired(false);
kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer());
kryo.register(Collections.EMPTY_LIST.getClass(), new CollectionsEmptyListSerializer());
kryo.register(Collections.EMPTY_MAP.getClass(), new CollectionsEmptyMapSerializer());
kryo.register(Collections.EMPTY_SET.getClass(), new CollectionsEmptySetSerializer());
kryo.register(Collections.singletonList("").getClass(), new CollectionsSingletonListSerializer());
kryo.register(Collections.singleton("").getClass(), new CollectionsSingletonSetSerializer());
kryo.register(Collections.singletonMap("", "").getClass(), new CollectionsSingletonMapSerializer());
kryo.register(BigDecimal.class, new DefaultSerializers.BigDecimalSerializer());
kryo.register(BigInteger.class, new DefaultSerializers.BigIntegerSerializer());
kryo.register(Pattern.class, new RegexSerializer());
kryo.register(BitSet.class, new BitSetSerializer());
kryo.register(URI.class, new URISerializer());
kryo.register(UUID.class, new UUIDSerializer());
kryo.register(GregorianCalendar.class, new GregorianCalendarSerializer());
kryo.register(InvocationHandler.class, new JdkProxySerializer());
UnmodifiableCollectionsSerializer.registerSerializers(kryo);
SynchronizedCollectionsSerializer.registerSerializers(kryo);
// 动态注册JodaDateTimeSerializer
try {
Class<?> clazz = Class.forName("org.joda.time.DateTime");
Serializer<?> serializer = (Serializer<?>) Class
.forName("de.javakaffee.kryoserializers.jodatime.JodaDateTimeSerializer")
.newInstance();
kryo.register(clazz, serializer);
} catch (Throwable thex) {
}
// 动态注册CGLibProxySerializer
try {
Class<?> clazz = Class.forName("de.javakaffee.kryoserializers.cglib.CGLibProxySerializer$CGLibProxyMarker");
Serializer<?> serializer = (Serializer<?>) Class
.forName("de.javakaffee.kryoserializers.cglib.CGLibProxySerializer")
.newInstance();
kryo.register(clazz, serializer);
} catch (Throwable thex) {
}
return kryo;
}
};
private KryoSerializer() {
}
public static byte[] write(Object obj) {
return write(obj, -1);
}
public static byte[] write(Object obj, int maxBufferSize) {
Kryo kryo = _threadLocalKryo.get();
Output output = new Output(1024, maxBufferSize);
kryo.writeClassAndObject(output, obj);
return output.toBytes();
}
public static Object read(byte[] bytes) {
Kryo kryo = _threadLocalKryo.get();
Input input = new Input(bytes);
return kryo.readClassAndObject(input);
}
}