当前位置: 首页 > news >正文

.net和java做网站比例百度关键词优化

.net和java做网站比例,百度关键词优化,文山专业网站建设,电商seo与sem是什么【KRouter】一个简单且轻量级的Kotlin Routing框架 KRouter(Kotlin-Router)是一个简单而轻量级的Kotlin路由框架。 具体来说,KRouter是一个通过URI来发现接口实现类的框架。它的使用方式如下: val homeScreen KRouter.route&l…

【KRouter】一个简单且轻量级的Kotlin Routing框架

KRouter(Kotlin-Router)是一个简单而轻量级的Kotlin路由框架。

具体来说,KRouter是一个通过URI来发现接口实现类的框架。它的使用方式如下:

val homeScreen = KRouter.route<Screen>("screen/home?name=zhangke")

之所以这样做,是因为在使用Voyager一段时间后,我发现模块之间的通信不够灵活,需要一些配置,而且使用DeepLink有点奇怪,所以我更喜欢使用路由来实现模块之间的通信,于是我开发了这个库。

这个库主要通过KSP、ServiceLoader和反射来实现。

使用方法

上述代码基本上就是使用的全部内容。

如前所述,这是用于发现接口实现类并通过URI匹配目标的库,因此我们首先需要定义一个接口。

interface Screen

然后我们有一个包含许多独立模块的项目,这些模块实现了这个接口,每个模块都不同,我们需要通过它们各自的路由(即URI)来区分它们。

// HomeModule
@Destination("screen/home")
class HomeScreen(@Router val router: String = "") : Screen// ProfileModule
@Destination("screen/profile")
class ProfileScreen : Screen {@Routerlateinit var router: String
}

现在我们有两个独立的模块,它们各自拥有自己的屏幕(Screens),并且它们都有自己的路由地址。

val homeScreen = KRouter.route<Screen>("screen/home?name=zhangke")
val profileScreen = KRouter.route<Screen>("screen/profile?name=zhangke")

现在,您可以通过KRouter获取这两个对象,并且这些对象中的路由属性将被分配给对KRouter.route的特定调用的路由。

现在,您可以在HomeScreenProfileScreen中获取通过URI传递的参数,并且可以使用这些参数进行一些初始化和其他操作。

@Destination

@Destination 注解用于标记目的地(Destination),包含两个参数:

  • route:目的地的唯一标识路由地址,必须是 URI 类型的字符串,不需要包含查询参数。
  • type:目的地的接口。如果类只有一个父类或接口,您无需设置此参数,它可以自动推断。但如果类有多个父类或接口,您需要通过 type 参数明确指定。

需要特别注意的是,被 @Destination 注解标记的类必须包含一个无参数构造函数,否则 ServiceLoader 无法创建对象。对于 Kotlin 类,您还需要确保构造函数的每个输入参数都具有默认值。

@Router

@Router 注解用于指定目的地类的哪个属性用于接收传入的路由参数,该属性必须是字符串类型。

使用此注解标记的属性将自动分配一个值,或者您可以不设置注解。例如,在上述示例中,当创建 HomeScreen 对象时,其 router 字段的值将自动设置为 screen/home?name=zhangke

特别要注意,如果被@Router注解的属性不在构造函数中,那么该属性必须声明为可修改的,即在 Kotlin 中应为 var 修饰的可变属性。

KRouter 是一个 Kotlin Object 类,它只包含一个函数:

inline fun <reified T : Any> route(router: String): T?

此函数接受一个泛型类型和一个路由地址。路由地址可以包含或不包含查询参数,但在匹配目的地时,查询参数将被忽略。匹配成功后,将使用此 URI 构造对象,并将 URI 传递给目标对象中的 @router 注解字段。

集成

首先,您需要在项目中集成 KSP。

https://kotlinlang.org/docs/ksp-overview.html

然后,添加以下依赖项:

// 模块的 build.gradle.kts
implementation("com.github.0xZhangKe.KRouter:core:0.1.5")
ksp("com.github.0xZhangKe.KRouter:compiler:0.1.5")

由于使用了 ServiceLoader,您还需要设置 SourceSet。

// 模块的 build.gradle.kts
kotlin {sourceSets.main {resources.srcDir("build/generated/ksp/main/resources")}
}

可能还需要添加 JitPack 仓库:

maven { setUrl("https://jitpack.io") }

工作原理

正如前面所提到的,KRouter 主要通过 ServiceLoader + KSP + 反射来实现。

这个框架由两个主要部分组成:编译阶段和运行时阶段。

KSP 插件
与 KSP 插件相关的代码位于编译器模块中。

KSP 插件的主要任务是根据 Destination 注解生成 ServiceLoader 的服务文件。

KSP 代码的其余部分基本相同,主要工作包括首先配置服务文件,然后根据注解获取类,最后通过 Visitor 进行迭代。您可以直接查看 KRouterVisitor 来了解更多细节。

override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {val superTypeName = findSuperType(classDeclaration)writeService(superTypeName, classDeclaration)
}

visitClassDeclaration 方法主要有两个主要功能,第一是获取父类,第二是编写或创建服务文件。

流程首先是获取指定类型的父类,如果没有父类,且只有一个父类时,可以直接返回,否则会引发异常。

// find super-type by type parameter
val routerAnnotation = classDeclaration.requireAnnotation<Destination>()
val typeFromAnnotation = routerAnnotation.findArgumentTypeByName("type")?.takeIf { it != badTypeName }// find single-type
if (classDeclaration.superTypes.isSingleElement()) {val superTypeName = classDeclaration.superTypes.iterator().next().typeQualifiedName?.takeIf { it != badSuperTypeName }if (!superTypeName.isNullOrEmpty()) {return superTypeName}
}

一旦获取到父类,我们需要创建一个文件,其文件名以接口或抽象类的权限作为所需的 ServiceLoader 文件名。

然后,我们将已实现类的权限名称写入该文件。

val resourceFileName = ServicesFiles.getPath(superTypeName)
val serviceClassFullName = serviceClassDeclaration.qualifiedName!!.asString()
val existsFile = environment.codeGenerator.generatedFile.firstOrNull { generatedFile ->generatedFile.canonicalPath.endsWith(resourceFileName)}
if (existsFile != null) {val services = existsFile.inputStream().use { ServicesFiles.readServiceFile(it) }services.add(serviceClassFullName)existsFile.outputStream().use { ServicesFiles.writeServiceFile(services, it) }
} else {environment.codeGenerator.createNewFile(dependencies = Dependencies(aggregating = false, serviceClassDeclaration.containingFile!!),packageName = "",fileName = resourceFileName,extensionName = "",).use {ServicesFiles.writeServiceFile(setOf(serviceClassFullName), it)}
}

KRouter主要有三个关键功能:

  1. 通过ServiceLoader获取接口的所有实现类。
  2. 将特定的目标类与URI进行匹配。
  3. 从URI构建目标类对象。
    第一件事非常简单:
inline fun <reified T> findServices(): List<T> {val clazz = T::class.javareturn ServiceLoader.load(clazz, clazz.classLoader).iterator().asSequence().toList()
}

一旦你获取到它,你就可以开始与URL进行匹配。

这个匹配的方式是获取每个目标类的Destination注解中的路由字段,然后将其与路由进行比较。

fun findServiceByRouter(serviceClassList: List<Any>,router: String,
): Any? {val routerUri = URI.create(router).baseUrival service = serviceClassList.firstOrNull {val serviceRouter = getRouterFromClassAnnotation(it::class)if (serviceRouter.isNullOrEmpty().not()) {val serviceUri = URI.create(serviceRouter!!).baseUriserviceUri == routerUri} else {false}}return service
}private fun getRouterFromClassAnnotation(targetClass: KClass<*>): String? {val routerAnnotation = targetClass.findAnnotation<Destination>() ?: return nullreturn routerAnnotation.router
}

匹配策略是忽略查询字段,只需通过baseUri进行匹配即可。

接下来的步骤是创建对象。有两种情况需要考虑:

第一种情况是@Router注解位于构造函数中,在这种情况下,需要再次使用构造函数创建对象。

第二种情况是@Router注解位于普通属性中。在这种情况下,可以直接使用ServiceLoader创建的对象,然后将值分配给它。

如果@Router注解位于构造函数中,您可以首先获取routerParameter,然后使用PrimaryConstructor重新创建对象。

private fun fillRouterByConstructor(router: String, serviceClass: KClass<*>): Any? {val primaryConstructor = serviceClass.primaryConstructor?: throw IllegalArgumentException("KRouter Destination class must have a Primary-Constructor!")val routerParameter = primaryConstructor.parameters.firstOrNull { parameter ->parameter.findAnnotation<Router>() != null} ?: return nullif (routerParameter.type != stringKType) errorRouterParameterType(routerParameter)return primaryConstructor.callBy(mapOf(routerParameter to router))
}

如果它是一个普通的变量属性,首先获取属性,然后进行一些类型权限和其他检查,然后调用setter方法分配值。

private fun fillRouterByProperty(router: String,service: Any,serviceClass: KClass<*>,
): Any? {val routerProperty = serviceClass.findRouterProperty() ?: return nullfillRouterToServiceProperty(router = router,service = service,property = routerProperty,)return service
}private fun KClass<*>.findRouterProperty(): KProperty<*>? {return declaredMemberProperties.firstOrNull { property ->val isRouterProperty = property.findAnnotation<Router>() != nullisRouterProperty}
}private fun fillRouterToServiceProperty(router: String,service: Any,property: KProperty<*>,
) {if (property !is KMutableProperty<*>) throw IllegalArgumentException("@Router property must be non-final!")if (property.visibility != KVisibility.PUBLIC) throw IllegalArgumentException("@Router property must be public!")val setter = property.setterval propertyType = setter.parameters[1]if (propertyType.type != stringKType) errorRouterParameterType(propertyType)property.setter.call(service, router)
}

上面是关于KRouter的全部内容,希望对你有所帮助!

GitHub

https://github.com/0xZhangKe/KRouter

http://www.dt0577.cn/news/1054.html

相关文章:

  • ppt模板免费下载哪个网站好云seo
  • 国内前十网站建设公司合肥网络优化公司有几家
  • 用织梦做网站有什么公司会要南京百度提升优化
  • 食品网站建设需求分析广州网站排名专业乐云seo
  • 开源网站下载新网域名注册
  • 网站怎么做架构图上海宝山网站制作
  • 软件开发app制作下载北京seo优化服务
  • 山东seo推广平台谷歌推广和seo
  • 合肥企业做网站网络服务合同
  • 淘宝店标logo在线制作免费seo策略工具
  • 文章标题-栏目名称-网站名 dede域名注册时间查询
  • 哪些网站是用c语言做的广东网站营销seo费用
  • 做亚马逊网站的账务处理西安seo优化
  • 做环评需要关注哪些网站公司网站注册流程和费用
  • 网站如何被百度收录权威解读当前经济热点问题
  • 左侧 导航 网站新闻10 30字
  • 博物馆网站建设目的怎么注册个人网站
  • 做简历哪个网站比较好软文推广代理
  • wordpress dream chaser成都搜索优化整站优化
  • 建设党建网站手机流畅优化软件
  • 上海移动端网站建设百度免费发布信息
  • 苏州网站建设上往建站恢复原来的百度
  • 怎么找人做淘宝网站网站百度收录秒收方法
  • 物联网网站设计广东知名seo推广多少钱
  • 软件商店安装下载2023win7优化大师下载
  • 做网站互联互通百度推广官方电话
  • wordpress页面修改专业网站优化公司
  • 手机网站怎么建百度人工优化
  • 做网站公司徐汇深圳网络推广怎么做
  • 网站seo合同写软文是什么意思