serializer-fory 是 EasyFK 框架的高性能序列化模块,基于 [Apache Fory](https://fury.apache.org/)(原 Fury)0.14.1 构建。提供 Java 内部序列化和跨语言(XLANG)序列化两种模式,通过 Spring Boot 自动配置实现类的自动扫描与注册,开箱即用。
本模块由两个子模块组成:
// 父级 build.gradle 声明了 easyfk-core 为所有子模块的编译期依赖
subprojects {
dependencies {
compileOnly project(':easyfk-core')
}
}dependencies {
api project(':easyfk-serializer:serializer-base')
api 'org.apache.fory:fory-core:0.14.1'
}| `easyfk-core` | 提供 `@SerializableClass` 注解和 `EmptyUtil` 工具 |
|---|---|
| `fory-core 0.14.1` | Apache Fory 序列化框架核心库 |
easyfk-serializer/
├── serializer-base/ # 抽象层
│ ├── build.gradle # (空,继承父级配置)
│ └── src/main/java/com/mcst/easyfk/serializer/base/
│ ├── SerializerClassRegister.java # SPI 接口:类注册器
│ ├── properties/
│ │ └── SerializerProperties.java # 配置属性
│ ├── config/
│ │ └── SerializerAutoConfiguration.java # 自动配置
│ └── init/
│ └── SerializerInitializer.java # 初始化器:扫描+注册
│
└── serializer-fory/ # Fory 实现层
├── build.gradle
└── src/main/java/com/mcst/easyfk/serializer/fory/
├── ForySerializer.java # 核心:Fory 序列化工具类
├── ForySerializerClassRegister.java # SPI 实现:Fory 类注册器
└── config/
└── ForySerializerAutoConfiguration.java # Fory 自动配置public interface SerializerClassRegister {
default void registerClass(List<Class<?>> classes) {
}
}序列化类注册器的函数接口。实现此接口可将扫描到的类注册到具体的序列化器中。模块通过 Spring 容器自动发现所有实现者。
方法说明:
定义在 easyfk-core 模块中:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SerializableClass {
}标记需要预注册到序列化器的类。启动时 SerializerInitializer 会扫描带有此注解的类并交给注册器处理。
配置前缀:easyfk.config.serializer
| `pre-register` | Boolean | `true` | 是否在启动时预注册序列化类。关闭后使用时动态注册 |
|---|---|---|---|
| `scan-packages` | List<String> | `[]` | 额外需要扫描的包路径列表(默认必扫 `com.mcst`) |
easyfk:
config:
serializer:
pre-register: true
cross-language: false
scan-packages:
- com.example.dto
- com.example.entity@AutoConfiguration
@EnableConfigurationProperties(SerializerProperties.class)
@ConditionalOnProperty(prefix = "easyfk.config.serializer", name = "pre-register",
havingValue = "true", matchIfMissing = true)
public class SerializerAutoConfiguration {
@Bean
public SerializerInitializer serializerInitializer() {
return new SerializerInitializer();
}
}生效条件: pre-register 为 true(默认生效)
注册 SerializerInitializer Bean,负责启动时扫描和注册类。
@AutoConfiguration
@ConditionalOnProperty(prefix = "easyfk.config.serializer", name = "pre-register",
havingValue = "true", matchIfMissing = true)
public class ForySerializerAutoConfiguration {
@Bean
public ForySerializerClassRegister forySerializerClassRegister() {
return new ForySerializerClassRegister();
}
}生效条件: pre-register 为 true(默认生效)
注册 ForySerializerClassRegister Bean,使 SerializerInitializer 能够自动发现并调用。
serializer-base:
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.mcst.easyfk.serializer.base.config.SerializerAutoConfigurationserializer-fory:
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.mcst.easyfk.serializer.fory.config.ForySerializerAutoConfigurationSerializerInitializer 实现 InitializingBean,在 Bean 初始化完成后自动执行:
Spring 容器启动
│
├─ SerializerAutoConfiguration 注册 SerializerInitializer
├─ ForySerializerAutoConfiguration 注册 ForySerializerClassRegister
│
└─ afterPropertiesSet() 触发
│
├─ 检查 preRegister 开关
│ └─ false → 跳过,日志提示
│
├─ 发现所有 SerializerClassRegister Bean
│ └─ 空 → 跳过
│
├─ 构建 ClassPath 扫描器
│ └─ 过滤器:@SerializableClass 注解
│
├─ 合并扫描包路径
│ ├─ 固定包:"com.mcst"
│ └─ 配置包:scanPackages
│
├─ 扫描所有候选类
│ └─ ClassPathScanningCandidateComponentProvider
│ └─ AnnotationTypeFilter(SerializableClass.class)
│
└─ 调用所有注册器
└─ serializerClassRegister.registerClass(classes)
└─ ForySerializerClassRegister
└─ ForySerializer.register(clazz) × NForySerializer 是序列化操作的入口,提供静态方法调用。
// 序列化
byte[] data = ForySerializer.serialize(myObject);
// 反序列化
MyClass obj = ForySerializer.deserialize(data);| `serialize(Object obj)` | 待序列化对象 | `byte[]` | null 返回空数组 |
|---|
需要先开启 cross-language: true 配置:
// 跨语言序列化
byte[] data = ForySerializer.serializeXLang(myObject);
// 跨语言反序列化
MyClass obj = ForySerializer.deserializeXLang(data);| `serializeXLang(Object obj)` | 待序列化对象 | `byte[]` | 未开启跨语言时抛 UnsupportedOperationException |
|---|
ForySerializer.register(MyClass.class);ThreadSafeFory javaFory = ForySerializer.getJavaFory();
ThreadSafeFory xlangFory = ForySerializer.getXLangFory();用于需要直接操作 Fory API 的高级场景。
SPI 接口的 Fory 实现:
public class ForySerializerClassRegister implements SerializerClassRegister {
@Override
public void registerClass(List<Class<?>> classes) {
for (Class<?> clazz : classes) {
ForySerializer.register(clazz);
}
}
}作为桥梁,将 SerializerInitializer 扫描到的类列表注册到 ForySerializer。
dependencies {
implementation project(':easyfk-serializer:serializer-fory')
}import com.mcst.easyfk.core.annotation.SerializableClass;
@SerializableClass
public class UserDto {
private String name;
private int age;
// getter/setter
}// 序列化
UserDto user = new UserDto();
user.setName("张三");
user.setAge(25);
byte[] bytes = ForySerializer.serialize(user);
// 反序列化
UserDto restored = ForySerializer.deserialize(bytes);easyfk:
config:
serializer:
cross-language: truebyte[] xlangData = ForySerializer.serializeXLang(user);
// 发送 xlangData 到 Python / Go / JavaScript 等语言的 Fory 客户端关闭预注册后,类在首次序列化时自动注册:
easyfk:
config:
serializer:
pre-register: false无需 @SerializableClass 注解,但首次序列化会有微小的注册开销。
easyfk-fory — 高性能序列化框架,加速数据传输与存储。