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

做美图 网站有哪些线上电脑培训班

做美图 网站有哪些,线上电脑培训班,网上商城建设杭州服务商,网站建设 amp 金手指排名效果好本篇文章目的是将 Springboot 和 Vertx 进行简单整合。整合目的仅仅是为了整活,因为两个不同的东西整合在一起提升的性能并没有只使用 Vertx 性能高,因此追求高性能的话这是在我来说不推荐。而且他们不仅没有提高很多性能甚至增加了学习成本 一、整合流…

本篇文章目的是将 Springboot 和 Vertx 进行简单整合。整合目的仅仅是为了整活,因为两个不同的东西整合在一起提升的性能并没有只使用 Vertx 性能高,因此追求高性能的话这是在我来说不推荐。而且他们不仅没有提高很多性能甚至增加了学习成本

一、整合流程

首先呢目标是将Vertx 最终整合成和使用Springboot web 一样简单的 httpserver。
步骤:

  1. 获取Springboot 所有的Bean
  2. 注册路由: 检查Bean 中是否是存在实现了 Router 的方法,并交给 router
  3. 开启服务器,等待请求

二、扫描 Bean

最终目标呢,是实现和使用Springboot 一样简便,所以就需要注解来对需要的方法进行标注

最终效果预览

@RouterController
class HelloRouter(val test :PlayerUnlockTechService
) {/*** 注册路由* 正则路由以 ^ 开始** 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@Rout("/hello")fun hello(response: HttpServerResponse, request: HttpServerRequest) {request.bodyHandler {response.end(test.getPlayerUnlockTechsByBuilding("BD12DC34624208045CCA1ECE32071F20").toString())}}
  1. 创建注解

主要注解有:

  • RouterController 标注类中有 Router 需要的路由实现
  • Rout 标注方法是个路由实现
  • AutoClose 标注方法执行完成后自动关闭连接
/**** @author : zimo* @date : 2025/01/03*/
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class RouterController/**** @author : zimo* @date : 2025/01/03*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Router(val path: String,val method: String = ""
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Rout(val path: String,val method: String = ""
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterGet(val path: String,val method: String = "GET"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPost(val path: String,val method: String = "POST"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPut(val path: String,val method: String = "PUT"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterDelete(val path: String,val method: String = "DELETE"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterPatch(val path: String,val method: String = "PATCH"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterHead(val path: String,val method: String = "HEAD"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class RouterOptions(val path: String,val method: String = "OPTIONS"
)@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class AutoClose
  1. 获取 Beans
    在当前类中注入 applicationContext 并通过 applicationContext.beanDefinitionNames 获取所有的 Bean
@Component
class RouterProcessor(val applicationContext: ApplicationContext) {/*** 初始化完成后的 bean 列表*/private val initializedBeanInstances by lazy {applicationContext.beanDefinitionNames.filter {it != this.javaClass.simpleName && it != Connection::class.simpleName}.mapNotNull {applicationContext.getBean(it)}}
}
  1. 检测出所有的Router 方法
    检测出是否被标注为了一个 Router 方法,并注册到 router
for (method in clazz.methods) {if (method.isAnnotationPresent(io.github.zimoyin.ra3.annotations.Router::class.java)) {val path = method.getAnnotation(io.github.zimoyin.ra3.annotations.Router::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)// order 可以放到注解里,这样可以动态设置了}.order(0).handler {// 执行方法的封装invoke(method, bean, it)}return}// ... 其他注解处理
}

三、执行Router方法

这里只有两个重点,一个是自动关闭,一个是执行方法传入的参数实例

  • 自动关闭,如果方法上存在 AutoClose 注解就在执行方法结束后尝试关闭连接
  • 方法参数,从Bean、Context 中获取。如果没有则通过上下文创建 Bean
fun invoke(method: Method, bean: Any, routingContext: RoutingContext) {val args = arrayListOf<Any>()val isHasAutoClose = method.isAnnotationPresent(AutoClose::class.java)// 获取方法需要的参数method.parameters.forEach {val bean0 = kotlin.runCatching { applicationContext.getBean(it.name, it.type) }.getOrNull()?: kotlin.runCatching { applicationContext.getBean(it.type) }.getOrNull()if (bean0 != null) {args.add(bean0)} else {args.add(createParameter(it, routingContext))}}//执行方法try {routingContext.request().paramsCharset = "UTF-8"val result = method.invoke(bean, *args.toTypedArray())kotlin.runCatching {// 自动关闭,如果方法上存在 `AutoClose` 注解就在执行方法结束后尝试关闭连接// 获取方法的返回值,并以方法的返回值作为自动关闭的参数if (isHasAutoClose) {val response = routingContext.response()response.putHeader("content-type", "application/json")if (method.returnType == Unit::class.java) {response.end()}if (result == null) {response.end()}if (result is String) {response.end(result)} else if (result is Number || result is Comparable<*>) {response.end(result.toString())} else {kotlin.runCatching {response.end(result.toJsonObject().toString())}.onFailure {response.end()logger.debug("自动关闭连接失败", it)}}}}} catch (e: InvocationTargetException) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败, $method 方法内部存在错误逻辑导致方法执行失败", e)} catch (e: Exception) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败", e)}}

获取 routingContext 中的参数,或者创建一个参数

private fun createParameter(value: Parameter, routingContext: RoutingContext): Any {val name = value.nameval type = value.typewhen (name) {"res", "response", "resp" -> return routingContext.response()"req", "request", "requ" -> return routingContext.request()"body", "reqBody", "requestBody" -> return routingContext.body()"headers", "header", "reqHeader", "requestHeader", "reqHeaders", "requestHeaders" -> return routingContext.request().headers()"query", "reqQuery", "requestQuery", "reqQueries", "requestQueries" -> return routingContext.queryParams()"data", "reqData", "requestData" -> return routingContext.data()"params", "reqParams", "requestParams" -> return routingContext.pathParams()"cookie", "reqCookie", "requestCookie" -> return routingContext.cookieMap()"session", "reqSession", "requestSession" -> return routingContext.session()"user", "reqUser", "requestUser" -> return routingContext.user()"bodyAsString", "reqBodyAsString", "requestBodyAsString" -> return routingContext.bodyAsString"bodyAsJson", "reqBodyAsJson", "requestBodyAsJson" -> return routingContext.bodyAsJson"bodyAsBuffer", "reqBodyAsBuffer", "requestBodyAsBuffer" -> return routingContext.body().buffer()"routingContext", "context", "routerContext", "routContext" -> return routingContext"rout", "router" -> return routingContext.currentRoute()"vertx", "vertxContext" -> return routingContext.vertx()"responseHeaders", "responseHeader" -> return routingContext.response().headers()"uri" -> return routingContext.request().uri()"absoluteURI" -> return routingContext.request().absoluteURI()"authority" -> return routingContext.request().authority()"isSSL", "ssl", "isSsl", "isSSl", "isssl", "SSL", "Ssl" -> return routingContext.request().isSSL}// 如果都不是以上的参数则创建一个kotlin.runCatching {applicationContext.autowireCapableBeanFactory.createBean(type)}.onSuccess {return it}throw IllegalArgumentException("Unable to parse parameters:$name")}

四、全部代码

通过 @EventListener(ApplicationReadyEvent::class) 注解来确保,该初始化方法可以在Springboot 启动完成后执行

注意: 需要提前将 Router 注册到Springboot

@Component
class RouterProcessor(val applicationContext: ApplicationContext) {private lateinit var router: io.vertx.ext.web.Routerprivate val logger = LoggerFactory.getLogger(RouterProcessor::class.java)@EventListener(ApplicationReadyEvent::class)fun init(event: ApplicationReadyEvent) {kotlin.runCatching {router = applicationContext.getBeanByName("router")for (bean in initializedBeanInstances) {registerBean(bean)}}.onFailure {logger.error(" Vertx WebRouter 初始化失败: ${it.message}", it)}}/*** 初始化完成后的 bean 列表*/private val initializedBeanInstances by lazy {applicationContext.beanDefinitionNames.filter {it != this.javaClass.simpleName &&it != Connection::class.simpleName}.mapNotNull {applicationContext.getBean(it)}}fun registerBean(bean: Any) {val clazz = bean.javaClassfor (method in clazz.methods) {runCatch {registerMethod(method, bean)}}}fun registerMethod(method: Method, bean: Any) {if (method.isAnnotationPresent(io.github.zimoyin.ra3.annotations.Router::class.java)) {val path = method.getAnnotation(io.github.zimoyin.ra3.annotations.Router::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(Rout::class.java)) {val path = method.getAnnotation(Rout::class.java).pathrouter.let {if (path.startsWith("^")) it.routeWithRegex(path.replaceFirst("^", ""))else it.route(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPost::class.java)) {val path = method.getAnnotation(RouterPost::class.java).pathrouter.let {if (path.startsWith("^")) it.postWithRegex(path.replaceFirst("^", ""))else it.post(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterGet::class.java)) {val path = method.getAnnotation(RouterGet::class.java).pathrouter.let {if (path.startsWith("^")) it.getWithRegex(path.replaceFirst("^", ""))else it.get(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPut::class.java)) {val path = method.getAnnotation(RouterPut::class.java).pathrouter.let {if (path.startsWith("^")) it.putWithRegex(path.replaceFirst("^", ""))else it.put(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPatch::class.java)) {val path = method.getAnnotation(RouterPatch::class.java).pathrouter.let {if (path.startsWith("^")) it.patchWithRegex(path.replaceFirst("^", ""))else it.patch(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterPatch::class.java)) {val path = method.getAnnotation(RouterDelete::class.java).pathrouter.let {if (path.startsWith("^")) it.deleteWithRegex(path.replaceFirst("^", ""))else it.delete(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterHead::class.java)) {val path = method.getAnnotation(RouterHead::class.java).pathrouter.let {if (path.startsWith("^")) it.headWithRegex(path.replaceFirst("^", ""))else it.head(path)}.order(0).handler {invoke(method, bean, it)}return}if (method.isAnnotationPresent(RouterOptions::class.java)) {val path = method.getAnnotation(RouterOptions::class.java).pathrouter.let {if (path.startsWith("^")) it.optionsWithRegex(path.replaceFirst("^", ""))else it.options(path)}.order(0).handler {invoke(method, bean, it)}return}}fun invoke(method: Method, bean: Any, routingContext: RoutingContext) {val args = arrayListOf<Any>()val isHasAutoClose = method.isAnnotationPresent(AutoClose::class.java)method.parameters.forEach {val bean0 = kotlin.runCatching { applicationContext.getBean(it.name, it.type) }.getOrNull()?: kotlin.runCatching { applicationContext.getBean(it.type) }.getOrNull()if (bean0 != null) {args.add(bean0)} else {args.add(createParameter(it, routingContext))}}//执行方法try {routingContext.request().paramsCharset = "UTF-8"val result = method.invoke(bean, *args.toTypedArray())kotlin.runCatching {if (isHasAutoClose) {val response = routingContext.response()response.putHeader("content-type", "application/json")if (method.returnType == Unit::class.java) {response.end()}if (result == null) {response.end()}if (result is String) {response.end(result)} else if (result is Number || result is Comparable<*>) {response.end(result.toString())} else {kotlin.runCatching {response.end(result.toJsonObject().toString())}.onFailure {response.end()logger.debug("自动关闭连接失败", it)}}}}} catch (e: InvocationTargetException) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败, $method 方法内部存在错误逻辑导致方法执行失败", e)} catch (e: Exception) {kotlin.runCatching { routingContext.response().end("Server Error!!!!") }logger.error("路由执行失败", e)}}private fun createParameter(value: Parameter, routingContext: RoutingContext): Any {val name = value.nameval type = value.typewhen (name) {"res", "response", "resp" -> return routingContext.response()"req", "request", "requ" -> return routingContext.request()"body", "reqBody", "requestBody" -> return routingContext.body()"headers", "header", "reqHeader", "requestHeader", "reqHeaders", "requestHeaders" -> return routingContext.request().headers()"query", "reqQuery", "requestQuery", "reqQueries", "requestQueries" -> return routingContext.queryParams()"data", "reqData", "requestData" -> return routingContext.data()"params", "reqParams", "requestParams" -> return routingContext.pathParams()"cookie", "reqCookie", "requestCookie" -> return routingContext.cookieMap()"session", "reqSession", "requestSession" -> return routingContext.session()"user", "reqUser", "requestUser" -> return routingContext.user()"bodyAsString", "reqBodyAsString", "requestBodyAsString" -> return routingContext.bodyAsString"bodyAsJson", "reqBodyAsJson", "requestBodyAsJson" -> return routingContext.bodyAsJson"bodyAsBuffer", "reqBodyAsBuffer", "requestBodyAsBuffer" -> return routingContext.body().buffer()"routingContext", "context", "routerContext", "routContext" -> return routingContext"rout", "router" -> return routingContext.currentRoute()"vertx", "vertxContext" -> return routingContext.vertx()"responseHeaders", "responseHeader" -> return routingContext.response().headers()"uri" -> return routingContext.request().uri()"absoluteURI" -> return routingContext.request().absoluteURI()"authority" -> return routingContext.request().authority()"isSSL", "ssl", "isSsl", "isSSl", "isssl", "SSL", "Ssl" -> return routingContext.request().isSSL}kotlin.runCatching {applicationContext.autowireCapableBeanFactory.createBean(type)}.onSuccess {return it}throw IllegalArgumentException("Unable to parse parameters:$name")}fun <T : Any> runCatch(block: () -> T): T? {try {return block()} catch (e: Exception) {logger.error("路由捕获到异常", e)}return null}
}

使用示例

/**** @author : zimo* @date : 2025/01/04*/
@RouterController
class HelloRouter(val test :PlayerUnlockTechService
) {/*** 注册路由* 正则路由以 ^ 开始* 请求处理方法: 所有* 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@Rout("/hello")
//    @RouterGetfun hello(response: HttpServerResponse, request: HttpServerRequest) {request.bodyHandler {response.end(test.getPlayerUnlockTechsByBuilding("BD12DC34624208045CCA1ECE32071F20").toString())}}/*** 注册路由(并自动关闭,将返回值发送会前端)* 正则路由以 ^ 开始* 请求处理方法: GET* 方法参数可以是 routingContext 或者 router 或者 routingContext 内的任何东西。以及其他的任何东西,或者 bean**/@RouterGet("/test/send_message/:message")@AutoClosefun send(response: HttpServerResponse, request: HttpServerRequest):String {return "你好"}}
}

Main 方法

/**** @author : zimo* @date : 2025/01/03*/
@SpringBootApplication
@EnableCaching
@MapperScan(basePackages = ["io.github.zimoyin.ra3.mapper"])
class ApplicationStart2(val vertx: Vertx,val router: Router
) {companion object {@JvmStaticfun main(args: Array<String>) {runApplication<ApplicationStart2>(*args)}}@PostConstructfun onStartVertxWeb() {vertx.createHttpServer().requestHandler(router).listen(8090).onSuccess {println("启动成功")}}
}@Configuration
class VertxConfig {@Bean("vertx")fun vertx(): Vertx {return Vertx.vertx()}@Bean("router")fun router(vertx: Vertx): Router? {return Router.router(vertx)}
}
http://www.hkea.cn/news/205054/

相关文章:

  • 公司部门kpi绩效考核指标模板河北百度seo软件
  • 印团网网站是哪家做的唯尚广告联盟
  • 网红营销网站seo综合查询怎么用的
  • 西安地区网站建设云推广
  • wordpress个人站2020年关键词排名
  • 网站建设企业公司石家庄新闻头条新闻最新今天
  • 道滘镇做网站百度统计
  • qq空间做宣传网站怎样建立自己的网站平台
  • 做设计一般用的素材网站是什么意思刷网站排名软件
  • 帮人做兼职的网站吗青岛seo服务哪家好
  • 贷款类网站怎样做网络营销的推广
  • 乐清做网站哪家好税收大数据
  • 校园网站建设需求天津放心站内优化seo
  • 哈尔滨微网站建设热搜在哪里可以看
  • 网站用oracle做数据库福州seo推广服务
  • 康保县城乡建设委员会网站营销型网站重要特点是
  • 手机做网站的步骤跨境电商有哪些平台
  • 请人做网站要多少网络事件营销
  • 网站页脚有什么作用厦门seo哪家强
  • 东莞百度提升优化优化推广网站推荐
  • 查企业网站有哪些站长统计app软件
  • 做a高清视频在线观看网站济源新站seo关键词排名推广
  • 刚做的网站怎么搜索不出来百度seo收录软件
  • 视频拍摄app站长工具seo综合查询广告
  • 新闻单位建设网站的意义武汉seo推广优化
  • 低价网站公司软文怎么写
  • 东莞市建设公共交易中心网站百度官网首页
  • 如何建立的网站能争钱优化营商环境 助推高质量发展
  • 做百度网站营销型网站建设排名
  • 网站域名被黑国际新闻最新消息战争