Solon 1.6.10 重要釋出,現在有官網嘍!

劉之西東發表於2021-12-24

關於官網

千呼萬喚始出來: https://solon.noear.org 。整了一個月多了,總體樣子有了。。。還得不斷接著整!

關於 Solon

Solon 是一個輕量級應用開發框架。支援 Web、Data、Job、Remoting、Cloud 等任何開發場景。短小而精悍!

  • 強調,剋制 + 簡潔 + 開放的原則
  • 力求,更小、更快、更自由的體驗

關於 Solon Cloud

Solon Cloud 定義了一系列分散式開發的介面標準和配置規範,相當於DDD模式裡的防腐層概念。是 Solon 的微服務架構模式開發解決方案。

關於本次更新

1、增加了第三方日誌框架的適配。以往是直接使用日誌框架,親合度差了一些

  • 新增 log4j2-solon-plugin 外掛
  • 新增 logback-solon-plugin 外掛

之前只適配了分散式日誌服務。現在也有本地的了。且,統一的配置方式(預設可以0配置):

solon.app:
  name: demoapp

# 以下為預設值,可以都不加,或者想改哪行加哪行(支援"雲端配置服務"進行配置,支援寫到"雲端日誌服務")
solon.logging.appender:
  console:
    level: TRACE
    pattern: "%highlight(%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [-%t][*%X{traceId}]%tags[%logger{20}]:) %n%msg%n"
  file:
    name: "logs/${solon.app.name}"
    level: INFO
    pattern: "%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [-%t][*%X{traceId}]%tags[%logger{20}]: %n%msg%n"
  cloud:
    level: INFO
    
# 記錄器級別的配置示例
solon.logging.logger:
  "features.*":
    level: WARN
  "org.jetty.demo.*":
    level: WARN    

並以 slf4j 做為統一的記錄介面

@Slf4j
@Service
public class DemoService{
    public void hello(){
        log.info("Hello world!");
    }
}

2、增加了一些便利介面和使用方式

  • 增加 Context::sessionAsInt, Context::sessionAsLong, Context::sessionAsDouble 介面
  • 增加 Context::sessionRemove 介面
  • 修復 solon.extend.stop 使用者ip獲取錯誤
  • 增加 mybatisplus-solon-plugin 為 globalConfig 注入內容的入口
  • 整合包 solon-api 預設新增 solon.extend.cors 外掛
  • 增加 主體流注入支援(@Body InputStream body)
  • 取消 solon.cache 外掛,由 solon.data 外掛整合相關功能,並提供工廠擴充套件機制
  • 增加 上下文特性,自動做為模板變數
  • 增加 JsonRenderFactory 的事件擴充套件支援
  • 增加 模板引擎配置 事件擴充套件機制

綜合一些特性,做個簡單的組合演示

public class DemoApp{
    public static void main(String[] args){
        Solon.start(DemoApp.class, args, app->{
            //增加預設的跨域支援(支援它的外掛,現在預設整合到了 solon-api 整合包裡)
            app.before(new CrossHandler().exposedHeaders("sign,token"));
        
            //定製渲染工廠(現在,不管哪個Json 框架都可基於 JsonRenderFactory 進行統一的定製)
            app.onEvent(JsonRenderFactory.class, f->{
                //json渲染時,將 long 型統一轉為 string
                f.addConvertor(Long.class, v-> String.valueOf(v));
            });
            
            //定製ftl模板配置
            app.onEvent(freemarker.template.Configuration.class, c -> {
                //增加經典模式支援
                c.setSetting("classic_compatible", "true");
                c.setSetting("number_format", "0.##");
            });
        });
    }
}

@Configuration
public class DemoConfig {
    //通過供應商模式,自動構建不同的快取服務型別(從原來的 solon.cache 轉移到 solon.data 外掛)
    @Bean
    public CacheService cache1(@Inject("cache1") CacheServiceSupplier supplier) {
        return supplier.get();
    }
}

@Controller
public class DemoController{
    @Mapping("/login")
    public void login(Context ctx){
        //到登入頁時,把 user_id 刪掉;確保使用者重新登入
        ctx.sessionRemove("user_id");
    }
    
    @Mapping("/admin")
    public void admin(Context ctx){
        long userId = ctx.sessionAsLong("user_id");
        if(userId == 0){
            //如果使用者id為0,則302跳轉到登入面
            ctx.redirect("/login");
        }
    }
    
    @Mapping("/admin/group/edit.save")
    public void admin_group_edit_save(long groupId, String name, @Body String meta){
        //groupId, name 通過 queryString 傳入;meta 是通過 body 傳入的純文字
    }
}

@Component
public class DemoFilter implements Filter{
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        //給所有模板增加全域性變數(或公共變數)
        ctx.attrSet("js", "/_static/js");
        ctx.attrSet("css", "/_static/css");
        
        chain.doFilter(ctx);
    }
}

3、能力或相容性增強

  • 增加 @Init 私有函式支援
  • 增加 @Bean 私有函式支援
  • 增加 @Inject("${xxx:}"),預設值為空的支援
  • 增加 StringSerializerRender 對 renderAndReturn 的支援
  • 增加 Context::renderAndReturn 支援非檢視資料
  • 調整 EventListener 充許 onEvent 丟擲異常
  • 調整 初始化失敗時,自動停掉所有外掛並結束程式
  • 增加 上下文特性,自動做為模板變數
  • 優化 配置注入"${xxx:def}"的相容性,def有":"符也沒關係了
  • 增加 Mvc 陣列引數注入時,自動以,號分離為陣列
  • 增加 @Init::index 屬性
  • 增加 容器掃描去重去處
  • 取消 @Param::format 屬性(自動處理增加17種格式)
@Configuration
public class DemoConfig {
    //以前必須要用 public
    @Bean
    private CacheService cache1(@Inject("cache1") CacheServiceSupplier supplier) {
        return supplier.get();
    }
    
    @Init
    private void init(){
        //...
    }
}

@Controller
public class DemoController{

    //以前是不能在預設值裡出現:號的
    @Inject("${user.name:noear:org}")
    String userName;
    
    @Mapping("/test")
    public String test(Context ctx){
        UserModel user = userService.get(1);
        
        //現在可以藉助上下文的渲染函式進行序列化(預設是json,也可指定渲染器)
        ctx.attrSet("@render","@json");
        String json = ctx.renderAndReturn(user);
        
        return Base64Utils.encode(json);
    }
}

快速瞭解 Solon 的材料:

《Solon 特性簡集,相較於 Springboot 有什麼區別?》

《Solon Cloud 分散式服務開發套件清單,感覺受與 Spring Cloud 的不同》

《Solon 的想法與架構筆記》

所謂更小:

核心0.1m,最小的介面開發單位0.2m(相較於 Dubbo、Springboot 的依賴包,小到可以乎略不計)

所謂更快:

本機http 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);

//手動為容器新增元件
Aop.wrapAndPut(DemoService.class);

附:專案地址

附:入門示例

更多系統的學習內容,建議參考官網

相關文章