Solon 是一個微型的Java RPC開發框架。項目從2018年啟動以來,參考過大量前人作品;歷時兩年,4000多次的commit;內核保持0.1m的身材,超高的跑分,良好的使用體驗。支持:RPC、REST API、MVC 等多種開發模式。
Solon 強調:克制 + 簡潔 + 開放的原則;力求:更小、更快、更自由的體驗。
項目地址:
所謂更小:
內核0.1m,最小開發單位0.2m(相比Dubbo、Springboot項目包,小到可以乎略不計)
所謂更快:
本機helloworld測試,Qps可達12萬之多。可參考:《helloworld_wrk_test》
所謂更自由:(代碼操控自由)
// 除了注解模式之外,還可以按需手動
//
//手動獲取配置(Props 為 Properties 增強版)
Props db = Solon.cfg().getProp("db");
//手動獲取容器里的Bean
UserService userService = Aop.get(UserService.class);
//手動監聽http post請求
Solon.global().post("/user/update", x-> userService.updateById(x.paramMap()));
//手動添加個RPC服務
Solon.global().add("/rpc/", HelloService.class, true);
//手動獲取一個RPC服務消費端
HelloService helloService = Nami.builder().create(HelloService.class);
本次版本重大變更:
1、增加 solon.extend.sessionstate.jwt 組件,以使用session state 的方式,使用 jwt.token
此組件有兩種應用場景:1)做管理后台的Session State,實現分布式Session的效果;2)做為接口的身份令牌
- 通過Cookie方式,做為管理后台的Session State;從而讓方便管理后台集群部署(用 solon.extend.sessionstate.redis 也能干這事兒)
Set-Cookie: TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTQ1NzEwNzAsImp0aSI6ImQ1Zjk5ZTk2MzA3NzRiNGZhNjRmNDJlMWIyNjQ0YjNkIiwiYmNmZG9ja19WYWxpZGF0aW9uX1N0cmluZyI6Ijl0MjIifQ._XY2p5IvItzL3xm3Iz6g2d1KpJG3y3cTn43uaM0dPS0;path=/;max-age=7200;domain=admin.demo.net;
- 通過Header方式,做為接口的身份令牌(通過配置,將jwt轉到header上)
server.session:
timeout: 7200
state.jwt:
requestUseHeader: true
responseUseHeader: true
使用demo
@Component(tag = "api")
public class API_login_test extends ApiBase {
@Logined
@Mapping("login.test")
public Result exec(Context ctx){
//獲取會話狀態(與常規session state一樣操作)
long user_id = ctx.session("user_id", 0);
//設置會話狀態
ctx.sessionSet("user_id", 100);
return Result.succeed();
}
}
TOKEN: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTQ1NzEwNzAsImp0aSI6ImQ1Zjk5ZTk2MzA3NzRiNGZhNjRmNDJlMWIyNjQ0YjNkIiwiYmNmZG9ja19WYWxpZGF0aW9uX1N0cmluZyI6Ijl0MjIifQ._XY2p5IvItzL3xm3Iz6g2d1KpJG3y3cTn43uaM0dPS0;path=/;max-age=7200;domain=admin.demo.net;
2、增加便利的文件下載支持(是下載,不是上傳)
@Controller
public class Demo{
@Mapping("/file/down1")
public void down1(Context ctx, String fileName){
File file = new File(fileName);
//通過上下文接口,輸出下載文件
ctx.outputAsFile(file);
}
@Mapping("/file/down2")
public File down1(String fileName){
File file = new File(fileName);
//通過MVC返回File,輸出下載文件
return file;
}
}
3、增加 @Logined 登錄驗證注解
//
// 如果未登錄,則會提示出錯(登錄時,將用戶id寫入session state記錄中)
//
@Controller
public class Demo{
@Logined
@Mapping("/file/api1")
public Result api1(){
return Result.succeed();
}
}
4、增加 solon.app.title 常態配置,便於管理后台的標題顯示
//通過 Solon.cfg().appTitle() 接口獲取
5、調整 Result 的默認成功碼為200,默認失敗碼為400(借用http的狀態碼)
使用 Result 做為簡單接口開發的統一格式輸出,是非常友好的選擇。類似:
@Controller
public class Demo{
@Mapping("/file/api1")
public Result api1(){
//直接返回成功結果:{cpde:200, description:"succeed"}
return Result.succeed();
}
@Mapping("/file/api2")
public Result<UserModel> api2(){
UserModel user = DbUserApi.getUser(12);
//返回成功結果:{cpde:200, description:"succeed", data:{user_id:1, name:"noear"}}
return Result.succeed(user);
}
@Mapping("/file/api3")
public Result api3(String mobile){
//返回錯誤結果:{cpde:4002001, description:"沒有手機號"}
return Result.failure(4002001, "沒有手機號");
}
}
如有需要,還可在啟動時調整默認的成功與失敗碼
public class DemoApp{
public static void main(String[] args){
Solon.start(DemoApp.class, args, app->{
Result.SUCCEED_CODE = 1;
Result.FAILURE_CODE = 0;
});
}
}