實現(xiàn)
整體實現(xiàn)參考OkHttp的interceptor責(zé)任鏈模式,支持Router跳轉(zhuǎn)中的認證,攔截,重定向,AB,(服務(wù)發(fā)現(xiàn),服務(wù)注入):類似Dagger
自定義Gradle plugin以及APT編譯階段根據(jù)注解生成代碼,并將Module,Service,Task,Route meta信息輸出到Json
功能
路由
泛平臺路由定義:支持多平臺的路由定義,native,web,flutter(暫未實現(xiàn)),applets(暫未實現(xiàn)),通過RouteType指定
自定義啟動流程:自定義創(chuàng)建Intent,適用于跳轉(zhuǎn)前,對一些參數(shù)的自定義處理。
-
統(tǒng)一路由協(xié)議:RouteRequest對象可以互轉(zhuǎn)一條統(tǒng)一路由協(xié)議:
("bilibili://video/BV1tC4y1H7yz?" + "-Bpt.types=native&" + "-Bpt.types=web&" + "-Bpt.flags=1&" + "-Bpt.prev=${Uri.encode("https://bilibili.com")}&" + "-Bpt.forward=${Uri.encode("https://baidu.com")}" 互轉(zhuǎn) "bilibili://video/BV1tC4y1H7yz".toBuilder() .routeTypes("native", "web") .flags(1) .prev("https://www.bilibili.com".toRouteRequest()) .forward("https://baidu.com".toRouteRequest()) .build() -
全局/模塊/路由三級攔截器
@Singleton @Services class CheckLoginInterceptor(private val loginService: LoginService) : RouteInterceptor { override fun intercept(chain: RouteInterceptor.Chain): RouteResponse { return if (!loginService.isLogin) { RouteResponse(RouteResponse.Code.UNAUTHORIZED, chain.request) } else { chain.proceed(chain.request) } } }CheckLoginInterceptor攔截器做了登陸校驗,如果未登錄會返回未認證,如果上面初始化時配置了
RouteAuthenticator,則會自動重定向到認證頁,且認證后自動轉(zhuǎn)發(fā)請求 -
靈活的路由匹配/捕獲規(guī)則:正則表達式,比如:
@Routes( "(?<scheme>https|http)://github.com/{org_name}/{project_name}" )相比其他Router框架編寫匹配規(guī)則稍微麻煩些
服務(wù)
- 聲明服務(wù):類上或者靜態(tài)方法(類似一個工廠方法)上聲明服務(wù)
- 消費服務(wù):@Inject注解或BRouter.services.getService(LoginService::class.java, "v1")
模塊
通過@ModuleOptions顯示聲明模塊,不聲明則隱式創(chuàng)建
模塊注解類可選注解ModuleActivator,處理回調(diào)onCreate onPostCreate
- 所有歸屬這個模塊的服務(wù),均隱式的依賴了這個模塊的onCreate
- 可以在構(gòu)造函數(shù)中聲明對其他模塊服務(wù)的依賴
- onCreate 與 onPostCreate 其實是特殊的 Task,因此可以在上面加TaskOptions注解來配置任務(wù)
- ON_DEMAND 模塊的 onCreate 在模塊的路由或者服務(wù)第一次被獲取時觸發(fā)或者手動觸發(fā)
- ON_INIT 則在BRouterCore.setUp觸發(fā),均為異步
任務(wù)
一次性的,用完即毀,僅適用于啟動任務(wù),且每個Task是歸屬一個模塊的
@TaskOptions("task2", dependencies = ["lib2.task1"], threadMode = ThreadMode.ANY)
public class Task2(@Named("v1") service: LoginService) : TaskAction {
override fun execute(task: Task) {
executor = Executors.newSingleThreadExecutor()
}
@Named("cached")
@TaskOutput(ExecutorService::class, Executor::class)
lateinit var executor: ExecutorService
}
構(gòu)造函數(shù)可依賴服務(wù),比較特別的是,@TaskOutput會產(chǎn)生服務(wù),而且因為 Task 一次性的性質(zhì),@TaskOutput產(chǎn)生的服務(wù)是單例的
數(shù)據(jù)
Json文件描述Router,Service,Task,Module通過解析可用于CI/CD/自動化/數(shù)據(jù)可視化;
自定義APT:通過MetaProcessor二次轉(zhuǎn)發(fā),方便遷移其他版本的路由到BRouter中
應(yīng)用
柔性降級
該倉庫示例本身沒有直接呈現(xiàn)柔性降級,但是可以結(jié)合后端RemoteConfig服務(wù)和方案中的攔截器實現(xiàn)柔性降級。比如:
- Module的攔截器和RemoteConfig配置實現(xiàn)模塊級別的降級
- App的攔截器和RemoteConfig配置結(jié)合實現(xiàn)頁面級別的降級(這時的攔截器類似統(tǒng)調(diào)中心)
路由攔截
支持App,Module以及Route自身的攔截,以及自定義的Launch方式擴展性高
具有Moudle的啟動的周期,INIT,CREATE,POSTCREATE