spring boot与ktor整合的实现方法
背景
在用了一阵子Ktor之后,深感基于协程的方便,但是公司的主要技术栈是SpringBoot,虽然已经整合了Kotlin,但是如果有Ktor加持则会更加的方便。因此作了一番研究后,也完全可以实现这样的整合了。
建立一个starter
首先新建一个Kotlin项目,在其build.gradle内加入对SpringBoot和Ktor的依赖,并同时加入对打为jar包的代码:
dependencies{
implementation"org.springframework.boot:spring-boot-starter-aop:${springBootVersion}"
implementation"io.ktor:ktor-jackson:${ktorVersion}"
compile"io.ktor:ktor-server-netty:${ktorVersion}"
compile"io.ktor:ktor-html-builder:${ktorVersion}"
testImplementation"org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
testCompile"io.ktor:ktor-client-apache:${ktorVersion}"
testCompile"io.ktor:ktor-server-test-host:${ktorVersion}"
}
jar{
from{
configurations.runtime.collect{zipTree(it)}
}
}
tasksourceJar(type:Jar){
fromsourceSets.main.allSource
classifier'sources'
}
对于SpringBoot来说,工程内的Configuration,Controller,Module都是必要的,因此也需要Ktor可以符合这些约定俗成的组件。
那么就简单来实现一下吧,首先实现Controller的代码,我们只需要让SpringBoot的Controller支持Ktor的路由写法就可以了:
interfaceKRouter{
funRouting.route()
}
@ContextDsl
funRouting.request(
path:String,
body:PipelineInterceptor
)=route(path){handle(body)}
然后实现基础的Module:
interfaceKModule{
funApplication.defaultRegister(
useCompress:Boolean=false,
redirectHttps:Boolean=false,
headers:String=""
){
install(ContentNegotiation){jackson{}}
install(PartialContent){maxRangeCount=10}
if(useCompress){
install(Compression){
gzip{priority=1.0}
deflate{
priority=10.0
minimumSize(1024)
}
}
}
if(redirectHttps){
install(HttpsRedirect){
sslPort=URLProtocol.HTTPS.defaultPort
permanentRedirect=true
}
}
if(headers!=""){
install(DefaultHeaders){
headers.toCookieMap().forEach{(t,u)->header(t,"$u")}
}
}
}
@ContextDsl
funApplication.register()
}
在这个Module内,defaultRegister是通过读取application.yml内的配置的参数来决定的,register是用来让用户覆盖,并实现额外的模块注册。
最后只需要实现Configuration就可以了,这里实现读取yml并且调用defaultRegister等方法:
/** *spring.ktor配置项 *@paramhost服务器主机名 *@paramport绑定端口 *@paramcompress是否启用压缩 *@paramredirectHttps是否自动重定向到https *@paramheaders默认的请求头 */ @ConfigurationProperties(prefix="spring.ktor") openclassKProperties( openvarhost:String="0.0.0.0", openvarport:Int=8080, openvarcompress:Boolean=false, openvarredirectHttps:Boolean=false, openvarheaders:String="" )
用这个类来映射yml内的配置,并且在取值后即可实现对模块,路由等的初始化:
@Configuration
@EnableConfigurationProperties(KProperties::class)
openclassKConfiguration{
@Resource
privatelateinitvarproperties:KProperties
@Bean
@ConditionalOnMissingBean
openfunengineFactory()=Netty
@Bean
@ConditionalOnMissingBean
openfunapplicationEngine(
engineFactory:ApplicationEngineFactory,
context:ApplicationContext
):ApplicationEngine{
returnembeddedServer(engineFactory,host=properties.host,port=properties.port){
valmodules=context.getBeansOfType(KModule::class.java).values
valroutes=context.getBeansOfType(KRouter::class.java).values
modules.forEach{it.apply{
defaultRegister(
useCompress=properties.compress,
redirectHttps=properties.redirectHttps,
headers=properties.headers)
register()
}}
routing{routes.forEach{it.apply{route()}}}
}.start()
}
@Bean
@ConditionalOnMissingBean
openfunapplication(
applicationEngine:ApplicationEngine,
context:ApplicationContext
):Application=applicationEngine.environment.application
}
好了,一个简单的starter就完成了,最后加入一些配置就可以完成:
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.isyscore.ktor.starter.configuration.KConfiguration
然后加入对配置项的描述:
additional-spring-configuration-metadata.json
{
"properties":[
{
"name":"spring.ktor.port",
"type":"java.lang.Integer",
"description":"服务启动时使用的端口号."
},
{
"name":"spring.ktor.host",
"type":"java.lang.String",
"description":"服务的主机IP或域名."
},
{
"name":"spring.ktor.compress",
"type":"java.lang.Boolean",
"description":"是否启用压缩."
},
{
"name":"spring.ktor.redirectHttps",
"type":"java.lang.Boolean",
"description":"是否自动重定向到https."
},
{
"name":"spring.ktor.headers",
"type":"java.lang.String",
"description":"默认的请求头,以分号隔开."
}
]
}
最后我们只需要将这个starter发布到私有的nexus就完成了:
$gradlepublish
使用starter
新建一个SpringBoot项目,并引入starter:
implementation"com.rarnu:spring-boot-starter-ktor:0.0.1"
此时可以先在yml内加入配置项:
spring: ktor: port:9000 compress:true headers:X-Engine=Ktor
然后来实现Configuration,Controller和Module:
TestConfiguration.kt
classTestConfiguration{
@Bean
funengineFactory()=TestEngine
}
TestModule.kt
@Component
classTestModule:KModule{
overridefunApplication.register(){
//TODO:installcustomplugins
}
}
TestController.kt
@Controller
classTestController:KRouter{
overridefunRouting.route(){
request("/"){
call.respond(mapOf("code"to"001","msg"to"操作成功。"))
}
get("/hello"){
call.respondText{"OK"}
}
}
}
完成后我们只需要写一个Application,并且启动服务即可:
SpringKtorApplication.kt
@SpringBootApplication openclassSpringKtorApplication funmain(args:Array){ runApplication (*args) }
现在就可以编译项目并且运行程序了:
$gradlecleanbuild $java-jartest-ktor.jar
总结
现在即可使用Ktor的写法来编写SpringBoot的路由了
可以使用Ktor协程
可以使用各种方便的Ktor插件
用上Ktor后,代码不麻烦了,心情也好了,效率更高了:)
到此这篇关于springboot与ktor整合的文章就介绍到这了,更多相关springboot与ktor整合内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。