SCM - 組件化通信工具
一切皆組件,當每個組件可看成一個微服務,組件化項目纔會真正解耦
組件化介紹:
通過一個類比的例子來介紹組件化
隨着業務的複雜度增大,業務線縱橫交錯,往往牽一髮而動全身。
我們希望業務代碼也能像一部智能手機。
入口模塊:應用桌面圖標,更像是home模塊,只提供入口;
業務模塊:通過appstore,下載我們需要的app,每個app(模塊)職責分明,鬧鐘,短信,電話……;
當某個模塊需求變化,並不想影響到其他業務線的大規模變動,只用更新當前app(模塊);
甚至 – 我的模塊、組件可以發到 appstore 給其他手機使用(插件化),每個應用可以資源互動(組件通信),可以增量更新…
所以:
一切皆組件,
每個模塊就是一個微服務,通過 rest api 來訪問,用完即走。
SCM介紹:
SCM就是用來定義api接口(通過註解在編譯期生成服務註冊表),通過請求(SCM.req),來拿到對應服務(action)的響應結果(ScCallback)的工具
SCM 不支持 Install Run
1: 通過註解註冊 @Action(name = “”) 聲明服務 類實現ScAction
2: 一個 Action 對應一個微服務
3: 通過對註解 Compiler 編譯期生成 -> 服務註冊表
4: Application 初始化 運行期掃描服務、緩存註冊表
5: 調用 SCM.req(String action,Callback A) 調用服務, 真正實現解耦
action —> module actionTable —> scmTable
使用:
1:根項目root-project的build.gradle
repositories {
...
maven {
url "https://dl.bintray.com/woaigmz/SCM"
}
}
2:你的每個module的build.gradle
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [KEY_MODULE_NAME:"Main"]
includeCompileClasspath true
}
}
}
...
dependencies {
compile 'com.woaigmz.scm:scm-api:0.0.4'
compile 'com.woaigmz.scm:scm-annotation:0.0.4'
annotationProcessor 'com.woaigmz.scm:scm-compiler:0.0.4'
}
3:初始化
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//對應每個module的 arguments = [KEY_MODULE_NAME:"Main"]
SCM.get().scanningSCMTable(new String[]{"Main", "Home"});
}
}
4:定義 Service(@Action)爲 module-home/actions/HomeLoadConfigAction,爲 home-module 提供給外界的api
//home-module/actions/HomeLoadConfigAction
@Action(name = "LoadConfig")
public class HomeLoadConfigAction implements ScAction {
@Override
public void invoke(Context context, String param, ScCallback callback) {
//模擬加載網絡數據
DataProvider.getConfig(callback);
}
}
//home-module/actions/HomeEntryAction
@Action(name = "HomeEntry")
public class HomeEntryAction implements ScAction {
@Override
public void invoke(Context context, String param, ScCallback callback) {
Intent intent = new Intent();
intent.setClass(context, HomeActivity.class);
context.startActivity(intent);
callback.onCallback(true, "HomeEntryAction:我把HomeActivity打開了", "");
}
}
//除頁面跳轉之外,大部分都是異步,業務情景不同,本框架不提供異步轉同步,開發者自己實現
5:請求:由action-name通過 SCM.req()方法在module-app / MainActivity 獲取 module-home/actions 下的服務action
private WeakHandler h = new WeakHandler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
String s = (String) msg.obj;
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
tvLoadConfig.setText(s);
return false;
}
});
//通過Action :"LoadConfig"請求; 響應:ScCallback 返回的是子線程進行的網絡請求結果要用handler
private void loadConfigByHomeModule() {
try {
SCM.get().req(MainActivity.this, "LoadConfig", new ScCallback() {
@Override
public void onCallback(boolean b, String data, String tag) {
if (b) {
Message obtain = Message.obtain();
obtain.obj = data;
if (h != null) {
h.sendMessage(obtain);
} else {
Toast.makeText(MainActivity.this, "WeakHandler has been Gc", Toast.LENGTH_SHORT).show();
}
}
}
});
} catch (Exception e) {
Log.e(Constants.SCM, e.getMessage());
}
}
//跳轉到 Home-module/view/HomeActivity
try {
SCM.get().req(MainActivity.this, "HomeEntry", new ScCallback() {
@Override
public void onCallback(boolean b, final String data, String tag) {
if (b)
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
Log.e(Constants.SCM, e.getMessage());
}
想法:
想到 java 後臺通過action來定義一個接口 ,servlet裏的 req,res,有更好的歡迎issue,star fork 。。。
具體實現思路可用參考項目:SCM地址:
註解工具的作用:action 加到註冊表,通過 annotationProcessor 編譯時註解,編譯期生成(SCMTable)表註冊
註解工具鏈接:ActionProcessor.java
SCM優點:
1:跨進程,通過傳遞的 json/string 字符實現類似 CC 的通過socket協議傳遞字符流
2:通過action對應的name,反射調用Action的invoke方法,實現解耦合 類似組件化項目 ModularizationArchitecture (aidl + service跨進程)
3:註冊表簡潔易懂,想到了R文件的生成,public static final “$actionName” = “@action對應action的實際包名”
4:只要原來的協議不變(@action(name=”XXX”))代碼重構不會對action有影響
5:編譯期生成SCMTable提高了掃描整個包的性能
maven上傳命令:
gradle install / gradlew bintrayUpload 上傳項目到 maven
查看有焦點的activity的包名
linux:adb shell dumpsys activity | grep “mFocusedActivity” / windows:adb shell dumpsys activity | findstr “mFocusedActivity”
不提供異步轉通過方法,因爲除了頁面跳轉,一般的action都是耗時操作,處理方式留給開發者具體問題具體對待,
幾種異步轉同步:
wait / notify
條件鎖
Future
CountDownLatch/CyclicBarrier
Handler
信號量