@
Solon 官網地址 https://solon.noear.org/
Solon GitHub原始碼地址 https://github.com/noear/solon
Solon for java,一個更現代感的,輕量級應用開發框架,崇尚剋制、簡潔、開放、生態設計理念。最新版本為1.10.7
Solon從專案啟動以來,參考過大量前人的作品。尤其是 Spring Boot、jFinal、Javalin 和 Asp.Net,吸取了諸多優點,且避開很多繁重的設計。歷時多年,核心始終保持 0.1Mb 的身材,超高的跑分,良好而自由的使用體驗。
目前支援jdk8、jdk11、jdk17、jdk19四個大版本,開發客製化方便,可通過組合不同的外掛快速開發不同的需求,開發人員幾乎可使用與SpringBoot相似的開發方式。其Solon Cloud 為一系列分散式開發的介面標準和設定規範,相當於DDD模式裡的防腐層概念,是 Solon 的微服務架構模式開發解決方案。在開發使用上官方也提供其與SpringBoot、SpringCloud、Dubbo的詳細區別,使用時查閱官方檔案即可。
Solon 根據官方提供資料,比傳統的Java應用特別是Spring生態開發的應用啟動快 5 ~ 10 倍,qps 高 2~ 3 倍,執行時記憶體節省 1/3 ~ 1/2,打包可以縮到 1/2 ~ 1/10。因此成為更現代感的應用開發框架,實現更快、更小、更少、更自由!
Ioc & Aop 內部結構
現有家簇成員圖譜
下載官方的helloworld範例 體驗下Solon 輕量和快。此外還可以下載官網提供豐富的配套範例:
專案 | 地址 | 說明 |
---|---|---|
solon-examples | https://gitee.com/noear/solon-examples | 配套"學習/科目學習"進行演示 |
下載完解壓後匯入Idea中,是個標準的maven專案,pom檔案引入solon的父依賴和核心依賴
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
</dependency>
一個組態檔app.yml,一個啟動類DemoApp,是不是和SpringBoot很相似,Solon 是一個容器型的應用開發框,在main方法中使用Solon.start啟動。app.yml內容如下:
server.port: 8080
solon.app:
name: demoapp
group: demo
這裡簡單修改hello方法的返回結果如下,可以直接執行,也可以先通過mvn clean package -DskipTests打包後再使用java -jar demo.jar執行。
幾小行程式碼一個http介面就完成,啟動速度非常快只用3ms,存取http://localhost:8080/hello?name=itxiaoshen 返回正確的結果
環境準備:建立MySQL資料庫test、表appx,並插入測試資料
CREATE TABLE `appx` (
`app_id` INT NOT NULL AUTO_INCREMENT COMMENT '應用ID',
`app_key` VARCHAR(40) DEFAULT NULL COMMENT '應用存取KEY',
`akey` VARCHAR(40) DEFAULT NULL COMMENT '(用於取代app id 形成的唯一key) //一般用於推廣註冊之類',
`ugroup_id` INT DEFAULT '0' COMMENT '加入的使用者組ID',
`agroup_id` INT DEFAULT NULL COMMENT '加入的應用組ID',
`name` VARCHAR(50) DEFAULT NULL COMMENT '應用名稱',
`note` VARCHAR(50) DEFAULT NULL COMMENT '應用備註',
`ar_is_setting` INT NOT NULL DEFAULT '0' COMMENT '是否開放設定',
`ar_is_examine` INT NOT NULL DEFAULT '0' COMMENT '是否稽核中(0: 沒稽核 ;1:稽核中)',
`ar_examine_ver` INT NOT NULL DEFAULT '0' COMMENT '稽核 中的版本號',
`log_fulltime` DATETIME DEFAULT NULL,
PRIMARY KEY (`app_id`),
UNIQUE KEY `IX_akey` (`akey`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='應用表';
INSERT appx(app_key,akey,ugroup_id,agroup_id,NAME,note,ar_is_setting,ar_is_examine,ar_examine_ver,log_fulltime)
VALUES('asdfghjk','aaaaabbbbb',100,1001,'抖音','時尚短視訊',0,1,1,NOW());
INSERT appx(app_key,akey,ugroup_id,agroup_id,NAME,note,ar_is_setting,ar_is_examine,ar_examine_ver,log_fulltime)
VALUES('sdfsdf','ccccdddd',102,1002,'招行','儲蓄',0,1,1,NOW());
INSERT appx(app_key,akey,ugroup_id,agroup_id,NAME,note,ar_is_setting,ar_is_examine,ar_examine_ver,log_fulltime)
VALUES('34543','eeeegggg',103,1003,'有道詞典','翻譯',0,1,1,NOW());
新增mybatis-plus和mysql相關依賴如下:
<dependency>
<groupId>org.noear</groupId>
<artifactId>mybatis-plus-extension-solon-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
app.yml檔案增加資料來源和mybatis-plus的設定
test.db1:
schema: rock
jdbcUrl: jdbc:mysql://192.168.40.100:3308/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: 123456
##預設
mybatis.db1:
typeAliases: #支援包名 或 類名(.class 結尾)
- "demo4031.model"
mappers: #支援包名 或 類名(.class 結尾)或 xml(.xml結尾 或 *.xml 結尾)
- "demo4031.dso.mapper"
# - "demo4031/dso/*.xml"
configuration:
cacheEnabled: false
mapUnderscoreToCamelCase: true
logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
globalConfig:
banner: false
metaObjectHandler: "demo4031.dso.MetaObjectHandlerImpl"
dbConfig:
logicDeleteField: "deleted"
logicDeleteValue: "2"
mapper介面和mapper.xml檔案與Spring整合Mybatis基本相同
@Mapper
public interface AppxMapper {
AppxModel appx_get();
Page<AppxModel> appx_get_page(Page<AppxModel> page);
AppxModel appx_get2(int app_id);
void appx_add();
Integer appx_add2(int v1);
@Select("SELECT * FROM INFORMATION_SCHEMA.TABLES")
List<DbTable> listTables();
}
再新增業務的Service和實現類,最後新增PlusController控制器實現
@Mapping("/plus/")
@Controller
public class PlusController {
@Inject
AppServicePlus appServicePlus;
@Mapping("test")
public AppxModel test() {
return appServicePlus.getById(2);
}
}
新增mybatis-plus分頁的PageController控制器實現
@Mapping("/page/")
@Controller
public class PageController {
@Db
AppxMapper appxMapper;
@Mapping("test")
public Object test() throws Throwable {
Page<AppxModel> page = new Page<>(2, 2);
return appxMapper.appx_get_page(page);
}
}
啟動程式後紀錄檔輸出如下
存取http://localhost:8080/plus/test,返回正確的結果
存取http://localhost:8080/page/test ,返回正確的分頁結果
引入依賴
<dependency>
<groupId>org.noear</groupId>
<artifactId>nami</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.socketd.client.websocket</artifactId>
</dependency>
簡單幾行程式碼就實現WebSocket的伺服器端程式設計
@ServerEndpoint(value = "/ws/demo/{id}")
public class WebSocket implements Listener {
@Override
public void onOpen(Session session) {
//path var
String id = session.param("id");
//query var
String token = session.param("token");
/*此處可以做籤權;對談的二次組織等...*/
}
@Override
public void onMessage(Session session, Message message) throws IOException {
//message.setHandled(true); //設為true,則不進入mvc路由
session.send("你發了:" + message.bodyAsString());
}
}
然後通過一個debug.htm通過javascript實現WebSocket收發功能,App啟動類開啟enableWebSocket
public class App {
public static void main(String[] args) {
//
// 啟動Solon,並開啟WebSocket監聽;同時新增/路徑跳轉
//
Solon.start(App.class, args, app -> app.enableWebSocket(true)).get("/", c -> {
c.redirect("/debug.htm");
});
}
}
啟動App後紀錄檔輸出如下
存取http://localhost:8080/ 輸入傳送資訊後伺服器端列印收到的輸入資訊
RPC的實現分為3個模組,RPC提供者的實現、公共模組、服務消費者,公共模組存放資料模型和介面,可以同時提供給提供者和消費者參照。
服務提供者新增solon-rpc依賴
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-rpc</artifactId>
</dependency>
服務提供者通過@Remoting註解實現RPC服務,程式碼如下
@Mapping("/user/")
@Remoting
public class UserServiceImpl implements UserService {
@Override
public UserModel getUser(Integer userId) {
UserModel model = new UserModel();
model.setId(userId);
model.setName("user-" + userId);
return model;
}
}
服務消費者新增如下依賴
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-rpc</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.cloud</artifactId>
</dependency>
app.yml組態檔設定服務發現的地址,也即是服務提供者提供的地址
server.port: 8080
solon.app:
name: demoapp
group: demo
solon.cloud.local:
discovery:
service:
local:
- "http://localhost:8081"
通過@NamiClient註解實現RPC遠端方法的呼叫
@Controller
public class UserController {
//使用負載
@NamiClient(name = "local",path = "/user/")
UserService userService;
@Mapping("test")
public UserModel test() {
UserModel user = userService.getUser(100);
System.out.println(user);
return user;
}
}
啟動服務提供者和服務消費者
存取服務消費者測試Controller的測試介面,http://localhost:8080/test ,返回正確結果
引入依賴
<dependency>
<groupId>org.noear</groupId>
<artifactId>nacos-solon-cloud-plugin</artifactId>
</dependency>
先準備好Nacos Server,這裡就直接使用前面文章已部署好的Nacos,建立好nacos的test名稱空間,為了演示讀取nacos的設定,在test下建立一個組為demo的test.properties,並新增db1.url的鍵值對。
然後在服務註冊端的本地app.yml組態檔新增相關nacos的設定資訊
server.port: 7112
solon.app:
namespace: test
group: demo
name: helloapi #發現服務使用的應用名(在Demo,將被NimaClient參照)
solon.cloud.nacos:
server: 192.168.50.95:8848 #nacos服務地址
username: nacos #nacos連結賬號
password: nacos #nacos連結密碼
宣告HelloService介面,服務註冊方實現介面,伺服器端的工作就完成了
@Mapping("/rpc/")@Remotingpublic class HelloServiceRemoteImp implements HelloService { @Override public String hello() { return "remote: hello"; }}
作為服務發現的使用者端本地app.yml組態檔新增相關nacos的設定資訊如下
solon.app: namespace: test group: demo #設定服務使用的預設組 name: helloapp #發現服務使用的應用名solon.cloud.nacos: server: 192.168.50.95:8848 #nacos服務地址 username: nacos #nacos連結賬號 password: nacos #nacos連結密碼 config: load: "test.properties"
測試的使用者端中也是通過註解@NamiClient注入HelloService介面,新增一個測試controller控制器演示
@Controllerpublic class TestController { //這是遠端的 @NamiClient HelloService helloService; @Mapping("/test") public String test() throws Exception { helloService.hello(); String temp = helloService.hello(); System.out.println("helloService return"+temp); return temp + "," + Solon.cfg().get("db1.url"); }}
已啟動服務註冊serverApp和服務發現ClientApp
檢視Nacos服務管理可以看下服務名已經正常註冊了
存取測試地址http://localhost:8080/test,可以看到成功呼叫服務註冊方的方法,也列印從Nacos設定中心的設定項值,至此,已經實現基於Nacos的設定、服務註冊和發現的基本功能。
**本人部落格網站 **IT小神 www.itxiaoshen.com