From 9145983193c051cb244921bf07155912bc60d0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Tue, 7 Feb 2023 09:42:12 +0800 Subject: [PATCH 01/15] seems kotlin (coroutines) is not fully support jigsaw yet --- document/jdk/Java-Preview.md | 1 + .../unicorn/strategy/TKMUserTypeStrategy.kt | 87 +++++++++++++++---- .../com/unicorn/vs/rest/RsLogController.java | 12 +++ .../src/main/java/module-info.java | 1 + 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/document/jdk/Java-Preview.md b/document/jdk/Java-Preview.md index 0d51257ac..b1e6b6489 100644 --- a/document/jdk/Java-Preview.md +++ b/document/jdk/Java-Preview.md @@ -74,6 +74,7 @@ - [Virtual Threads in Spring 6.x](https://spring.io/blog/2022/10/11/embracing-virtual-threads) - [Blog-Understanding Java's Project Loom](https://www.marcobehler.com/guides/java-project-loom?mkt_tok=NDI2LVFWRC0xMTQAAAGIcjkwHcDNBFot5rdRdBEUuF6VoChWteoULzKapDGmwmAvhMcx0grhQ0louho-dN1ckoHsIo1dWoRkkUbuaEtY9jNg8gRmb1XxVmmNrLmADNkSKVgN) - [IntelliJ IDEA Conf 2022 | Project Loom: Revolution in Concurrency or Obscure Implementation Detail?](https://www.youtube.com/watch?v=0DUlUzqr09I) +- [Running Kotlin Coroutines on Project Loom](https://kt.academy/article/dispatcher-loom) 通过JProfiler可以查看Thread的情况,这一点不得不说收费的就是不一样。VisualVM和jconsole都看不到类型信息。 可以看的基本的main Thread,及19后听到的CarrierThreads和VirtualThreads diff --git a/valentine-starter/src/main/java/com/unicorn/strategy/TKMUserTypeStrategy.kt b/valentine-starter/src/main/java/com/unicorn/strategy/TKMUserTypeStrategy.kt index f98447cf8..7fdf7de43 100644 --- a/valentine-starter/src/main/java/com/unicorn/strategy/TKMUserTypeStrategy.kt +++ b/valentine-starter/src/main/java/com/unicorn/strategy/TKMUserTypeStrategy.kt @@ -15,12 +15,17 @@ */ package com.unicorn.strategy -import com.lwohvye.core.utils.ConcurrencyUtils import com.lwohvye.sys.modules.system.annotation.UserTypeHandlerAnno import com.lwohvye.sys.modules.system.strategy.ExtraUserTypeStrategy import kotlinx.coroutines.* +import org.apache.logging.log4j.LogManager.getLogger +import org.jetbrains.annotations.BlockingExecutor import org.springframework.security.core.GrantedAuthority import org.springframework.stereotype.Component +import java.util.concurrent.Executors +import kotlin.time.ExperimentalTime +import kotlin.time.measureTime + @Component @UserTypeHandlerAnno(typeName = "FOUR") @@ -36,30 +41,28 @@ class TKMUserTypeStrategy : ExtraUserTypeStrategy() { // Coroutines can perfectly benefit from Loom: A Coroutine always relies on a thread for its execution. // This Thread can also be a VirtualThread. The advantage of having a VirtualThread executing a Coroutine is that all IO operations, // concurrency locks etc. will behave in a non-blocking fashion, wasting no resources. - ConcurrencyUtils.structuredExecute( - null, null, - { - // 使用launch{}函数 启动一个协程 - GlobalScope.launch { - runBlocking { // 在 runBlocking {} 包装中使用 delay,它启动了一个协程并等待直到它结束 - delay(1000) - } - println("Hello") - } - }, { - val result = GlobalScope.async { - workload(16) // 调用函数 - } - runBlocking { - println(result.await()) - } + GlobalScope.launch { + runBlocking { // 在 runBlocking {} 包装中使用 delay,它启动了一个协程并等待直到它结束 + delay(1000) } - ) + println("Hello") + } Thread.sleep(2000) // 等待 2 秒钟 println("Stop") //_____________ + val result = GlobalScope.async { + workload(16) // 调用函数 + } + runBlocking { + println(result.await()) + } + + vtCarrier() + xCoroutine() + //_____________ + return emptyList() } @@ -67,4 +70,50 @@ class TKMUserTypeStrategy : ExtraUserTypeStrategy() { delay(1000) return n + 2 } + + // Define a Custom Dispatcher + // What if instead of blocking a regular thread, we run it on one of Project Loom’s virtual threads, + // effectively turning the blocking code into something non-blocking while still being Coroutine compatible? + val Dispatchers.LOOM: @BlockingExecutor CoroutineDispatcher + get() = Executors.newVirtualThreadPerTaskExecutor().asCoroutineDispatcher() + + // use Loom. This will need some time to warm up, overhead. 22s for 100_000 + @OptIn(ExperimentalTime::class) + fun vtCarrier() = runBlocking { + + val log = getLogger() + + measureTime { + supervisorScope { + repeat(100_000) { + launch(Dispatchers.LOOM) { + Thread.sleep(1000) + } + } + } + }.also(log::info) + + Unit + + } + + // use Kotlinx Coroutines. While this is ballpark. 10s for 100_000 + @OptIn(ExperimentalTime::class) + fun xCoroutine() = runBlocking { + + val log = getLogger() + + measureTime { + supervisorScope { + repeat(100_000) { + launch { + delay(1000) + } + } + } + }.also(log::info) + + Unit + + } } diff --git a/valentine-starter/src/main/java/com/unicorn/vs/rest/RsLogController.java b/valentine-starter/src/main/java/com/unicorn/vs/rest/RsLogController.java index 138b8444d..737334978 100644 --- a/valentine-starter/src/main/java/com/unicorn/vs/rest/RsLogController.java +++ b/valentine-starter/src/main/java/com/unicorn/vs/rest/RsLogController.java @@ -22,10 +22,13 @@ import com.lwohvye.core.utils.result.ResultInfo; import com.lwohvye.sys.common.annotation.ApiVersion; import com.lwohvye.sys.modules.infrastructure.constants.LogRecordType; +import com.lwohvye.sys.modules.system.strategy.AuthHandlerContext; import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; @@ -61,6 +64,11 @@ public void who() { log.warn(" The module of Cur-Starter is {} ", this.getClass().getModule()); } + @Lazy + @Autowired + private AuthHandlerContext authHandlerContext; + + /** * 访问首页提示 * 因为自定义了处理逻辑,所以下面这俩的RequestCondition是不一样的,所以能共存,且因为定义了优先新版本,所以在v1时走第一个,[v2+ 走第二个 @@ -73,6 +81,10 @@ public void who() { @ApiVersion @AnonymousGetMapping("/valentine/{version}/p2p") public String index(@PathVariable String version) { + + var instance = authHandlerContext.getInstance(4); + instance.grantedAuth(2022L); + return null; // return "Backend service started successfully" } diff --git a/valentine-starter/src/main/java/module-info.java b/valentine-starter/src/main/java/module-info.java index 6000ffdd9..45311a2cc 100644 --- a/valentine-starter/src/main/java/module-info.java +++ b/valentine-starter/src/main/java/module-info.java @@ -11,6 +11,7 @@ requires com.mzt.logapi; requires kotlin.stdlib; requires kotlinx.coroutines.core.jvm; + requires org.apache.logging.log4j; // requires captcha; exports com.unicorn.vs.rest to spring.beans, spring.aop, spring.web; From 0389597a598d5fd0eda1f9110753998bfbbf9c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Wed, 8 Feb 2023 08:05:37 +0800 Subject: [PATCH 02/15] try use oracle --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/docker-image.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 75f83cfab..82193c05e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,12 +41,12 @@ jobs: uses: actions/checkout@v3 # see: https://github.com/marketplace/actions/setup-java-jdk - name: Setup Java JDK - uses: actions/setup-java@v3.9.0 + uses: actions/setup-java@v3.10.0 with: # The Java version to set up. Takes a whole or semver Java version. See examples of supported syntax in README file java-version: '19' # Java distribution. See the list of supported distributions in README file - distribution: 'corretto' + distribution: 'oracle' # The package type (jdk, jre, jdk+fx, jre+fx) #java-package: # optional, default is jdk # The architecture of the package diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ff788209d..f604137e2 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -21,10 +21,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - name: Set up JDK - uses: actions/setup-java@v3.9.0 + uses: actions/setup-java@v3 with: java-version: '19' - distribution: 'corretto' + distribution: 'temurin' check-latest: true server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file From 7ee139a103288e085b94b349fa7ebeba537bb0df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Fri, 10 Feb 2023 08:54:43 +0800 Subject: [PATCH 03/15] mapstruct-spring-extensions seems unused --- gradle.properties | 4 ++-- unicorn-code-gen/build.gradle | 1 - unicorn-core/build.gradle | 5 +++-- .../src/main/java/com/lwohvye/core/base/BaseMapper.java | 1 + unicorn-core/src/main/java/module-info.java | 1 - unicorn-logging/build.gradle | 1 - unicorn-reactive/build.gradle | 1 - unicorn-security/build.gradle | 1 - unicorn-sys-api/build.gradle | 1 - unicorn-tp-tools/build.gradle | 1 - valentine-starter/build.gradle | 1 - 11 files changed, 6 insertions(+), 12 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4a0908503..347c925f8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ commonsBeanutilsVersion=1.9.4 commonsConfigurationVersion=2.8.0 easyCaptchaVersion=1.6.2 fastutilVersion=8.5.9 -hutoolVersion=5.8.10 +hutoolVersion=5.8.12 ip2regionVersion=3.0.1 jjwtVersion=0.11.5 kotlinVersion=1.8.0 @@ -28,7 +28,7 @@ log4jdbcVersion=1.18 logbackVersion=1.4.5 logstashVersion=7.2 mapstructVersion=1.5.3.Final -mapstructSpringVersion=0.1.2 +mapstructSpringExtensionsVersion=1.0.0 oshiCoreVersion=6.4.0 poiVersion=5.2.2 quartzVersion=2.3.2 diff --git a/unicorn-code-gen/build.gradle b/unicorn-code-gen/build.gradle index aab926844..bf94b2950 100644 --- a/unicorn-code-gen/build.gradle +++ b/unicorn-code-gen/build.gradle @@ -62,7 +62,6 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') } diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index f2038a823..dd2a5714d 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -82,7 +82,9 @@ dependencies { api "org.apache.poi:poi-ooxml:$poiVersion" implementation "xerces:xercesImpl:$xercesVersion" api "org.mapstruct:mapstruct:$mapstructVersion" - api "org.mapstruct.extensions.spring:mapstruct-spring-extensions:$mapstructSpringVersion" +// mapstruct-spring-extensions seems unused + api "org.mapstruct.extensions.spring:mapstruct-spring-annotations:${mapstructSpringExtensionsVersion}" + annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}" api 'org.hibernate.validator:hibernate-validator' api "nl.basjes.parse.useragent:yauaa:$yauaaVersion" api 'com.github.ben-manes.caffeine:caffeine' @@ -116,7 +118,6 @@ extraJavaModuleInfo { module('commons-collections-3.2.2.jar', 'org.apache.commons.collections', '3.2.2') automaticModule('commons-logging-1.2.jar', 'org.apache.commons.logging')*/ automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') } diff --git a/unicorn-core/src/main/java/com/lwohvye/core/base/BaseMapper.java b/unicorn-core/src/main/java/com/lwohvye/core/base/BaseMapper.java index 9c833c184..9d2fb7745 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/base/BaseMapper.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/base/BaseMapper.java @@ -47,6 +47,7 @@ public interface BaseMapper extends Converter { /** * Entity转DTO,由Spring的Converter替换。这个只能单向转换,当都是这个方向时,用这个可以减少Mapper的注入 * @see https://mapstruct.org/news/2022-02-07-mapstruct-spring-extensions-0-1-1-released/ + * but mapstruct-spring-extensions seems unused, things works well just with spring converter * * @param entity / * @return / diff --git a/unicorn-core/src/main/java/module-info.java b/unicorn-core/src/main/java/module-info.java index dfc7e9868..8b95c81a8 100644 --- a/unicorn-core/src/main/java/module-info.java +++ b/unicorn-core/src/main/java/module-info.java @@ -48,7 +48,6 @@ requires transitive org.hibernate.validator; requires transitive org.jetbrains.annotations; requires transitive org.mapstruct; - requires transitive org.mapstruct.extensions.spring; requires transitive org.slf4j; requires transitive org.springdoc.openapi.common; requires transitive org.redisson; diff --git a/unicorn-logging/build.gradle b/unicorn-logging/build.gradle index f418dbc8b..de4c64a4b 100644 --- a/unicorn-logging/build.gradle +++ b/unicorn-logging/build.gradle @@ -59,7 +59,6 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') } diff --git a/unicorn-reactive/build.gradle b/unicorn-reactive/build.gradle index 6c974070c..8b7191c89 100644 --- a/unicorn-reactive/build.gradle +++ b/unicorn-reactive/build.gradle @@ -67,7 +67,6 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') } diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index 78eb02668..ed45b32f9 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -87,7 +87,6 @@ extraJavaModuleInfo { automaticModule("io.jsonwebtoken:jjwt-impl", 'io.jsonwebtoken.impl') automaticModule("io.jsonwebtoken:jjwt-jackson", 'io.jsonwebtoken.jackson') automaticModule("com.jcraft:jsch", 'com.jcraft.jsch') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.quartz-scheduler:quartz", 'org.quartz') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("org.springframework.retry:spring-retry", 'spring.retry') diff --git a/unicorn-sys-api/build.gradle b/unicorn-sys-api/build.gradle index e3086caea..4d404e4d2 100644 --- a/unicorn-sys-api/build.gradle +++ b/unicorn-sys-api/build.gradle @@ -59,7 +59,6 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') } diff --git a/unicorn-tp-tools/build.gradle b/unicorn-tp-tools/build.gradle index 961c9c2e6..885984f07 100644 --- a/unicorn-tp-tools/build.gradle +++ b/unicorn-tp-tools/build.gradle @@ -63,7 +63,6 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') module('org.eclipse.angus:jakarta.mail', 'jakarta.mail', '1.0.0') { diff --git a/valentine-starter/build.gradle b/valentine-starter/build.gradle index 94b996135..5e21d01ca 100644 --- a/valentine-starter/build.gradle +++ b/valentine-starter/build.gradle @@ -41,7 +41,6 @@ extraJavaModuleInfo { automaticModule("io.jsonwebtoken:jjwt-impl", 'io.jsonwebtoken.impl') automaticModule("io.jsonwebtoken:jjwt-jackson", 'io.jsonwebtoken.jackson') automaticModule("com.jcraft:jsch", 'com.jcraft.jsch') - automaticModule("org.mapstruct.extensions.spring:mapstruct-spring-extensions", 'org.mapstruct.extensions.spring') automaticModule("org.quartz-scheduler:quartz", 'org.quartz') automaticModule("org.redisson:redisson", 'org.redisson') automaticModule("org.springframework.retry:spring-retry", 'spring.retry') From 08556681710a111c188b56bf5019aa8e1b5a160b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Fri, 10 Feb 2023 09:11:13 +0800 Subject: [PATCH 04/15] we can confirm that we don't need mapstruct-spring-extensions in our scenario --- unicorn-core/build.gradle | 2 +- unicorn-security/build.gradle | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index dd2a5714d..831dd67bf 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -84,7 +84,6 @@ dependencies { api "org.mapstruct:mapstruct:$mapstructVersion" // mapstruct-spring-extensions seems unused api "org.mapstruct.extensions.spring:mapstruct-spring-annotations:${mapstructSpringExtensionsVersion}" - annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}" api 'org.hibernate.validator:hibernate-validator' api "nl.basjes.parse.useragent:yauaa:$yauaaVersion" api 'com.github.ben-manes.caffeine:caffeine' @@ -98,6 +97,7 @@ dependencies { log4jdbcRuntimeOnly "com.lwohvye.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:$log4jdbcVersion" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion" + annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}" } // TODO: 2022/9/1 这个无法传递,就很不好 diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index ed45b32f9..6173f22b7 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -75,6 +75,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' annotationProcessor "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion" + annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}" } extraJavaModuleInfo { From b237bb5da6c06e2c65d1107709f6841458350c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Sat, 11 Feb 2023 08:15:53 +0800 Subject: [PATCH 05/15] update auto-module-name --- unicorn-code-gen/build.gradle | 6 ++--- unicorn-core/build.gradle | 18 +++------------ unicorn-core/src/main/java/module-info.java | 6 ++--- unicorn-logging/build.gradle | 6 ++--- unicorn-reactive/build.gradle | 6 ++--- unicorn-security/build.gradle | 22 +++++++++---------- .../src/main/java/module-info.java | 16 +++++++------- unicorn-starter/pom.xml | 4 ++-- .../src/main/java/module-info.java | 4 ++-- unicorn-sys-api/build.gradle | 6 ++--- unicorn-tp-tools/build.gradle | 6 ++--- valentine-search/pom.xml | 2 +- valentine-starter/build.gradle | 22 +++++++++---------- .../src/main/java/module-info.java | 2 +- 14 files changed, 57 insertions(+), 69 deletions(-) diff --git a/unicorn-code-gen/build.gradle b/unicorn-code-gen/build.gradle index bf94b2950..49ac8e810 100644 --- a/unicorn-code-gen/build.gradle +++ b/unicorn-code-gen/build.gradle @@ -61,7 +61,7 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index 831dd67bf..732cb8cd8 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -105,21 +105,9 @@ extraJavaModuleInfo { failOnMissingModuleInfo.set(false) // This does not have to be a complete description (e.g. here 'org.apache.commons.collections' does not export anything here). // It only needs to be good enough to work in the context of this application we are building. -/* module('commons-beanutils-1.9.4.jar', 'org.apache.commons.beanutils', '1.9.4') { - exports('org.apache.commons.beanutils') - - requires('org.apache.commons.logging') - requires('java.sql') - requires('java.desktop') - } - module('commons-cli-1.4.jar', 'org.apache.commons.cli', '3.2.2') { - exports('org.apache.commons.cli') - } - module('commons-collections-3.2.2.jar', 'org.apache.commons.collections', '3.2.2') - automaticModule('commons-logging-1.2.jar', 'org.apache.commons.logging')*/ - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } tasks.named('compileJava') { diff --git a/unicorn-core/src/main/java/module-info.java b/unicorn-core/src/main/java/module-info.java index 8b95c81a8..7833fe0a9 100644 --- a/unicorn-core/src/main/java/module-info.java +++ b/unicorn-core/src/main/java/module-info.java @@ -33,7 +33,7 @@ requires transitive com.fasterxml.jackson.annotation; requires transitive com.fasterxml.jackson.databind; requires transitive com.github.benmanes.caffeine; - requires transitive cn.hutool; + requires transitive hutool.all; requires transitive io.swagger.v3.oas.models; requires transitive io.swagger.v3.oas.annotations; requires transitive lombok; @@ -50,8 +50,8 @@ requires transitive org.mapstruct; requires transitive org.slf4j; requires transitive org.springdoc.openapi.common; - requires transitive org.redisson; - requires net.coobird.thumbnailator; + requires transitive redisson; + requires thumbnailator; exports com.lwohvye.core.advice; exports com.lwohvye.core.annotation; diff --git a/unicorn-logging/build.gradle b/unicorn-logging/build.gradle index de4c64a4b..a0fb3965b 100644 --- a/unicorn-logging/build.gradle +++ b/unicorn-logging/build.gradle @@ -58,7 +58,7 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } diff --git a/unicorn-reactive/build.gradle b/unicorn-reactive/build.gradle index 8b7191c89..eb58633c2 100644 --- a/unicorn-reactive/build.gradle +++ b/unicorn-reactive/build.gradle @@ -66,7 +66,7 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index 6173f22b7..55edd1716 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -80,16 +80,16 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("io.github.mouzt:bizlog-sdk", 'com.mzt.logapi') - automaticModule("com.github.whvcse:easy-captcha", 'com.wf.captcha') - automaticModule("ch.ethz.ganymed:ganymed-ssh2", 'ch.ethz.ssh2') - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("io.jsonwebtoken:jjwt-api", 'io.jsonwebtoken.api') - automaticModule("io.jsonwebtoken:jjwt-impl", 'io.jsonwebtoken.impl') - automaticModule("io.jsonwebtoken:jjwt-jackson", 'io.jsonwebtoken.jackson') - automaticModule("com.jcraft:jsch", 'com.jcraft.jsch') - automaticModule("org.quartz-scheduler:quartz", 'org.quartz') - automaticModule("org.redisson:redisson", 'org.redisson') + automaticModule("io.github.mouzt:bizlog-sdk", 'bizlog.sdk') + automaticModule("com.github.whvcse:easy-captcha", 'easy.captcha') + automaticModule("ch.ethz.ganymed:ganymed-ssh2", 'ganymed.ssh2') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("io.jsonwebtoken:jjwt-api", 'jjwt.api') + automaticModule("io.jsonwebtoken:jjwt-impl", 'jjwt.impl') + automaticModule("io.jsonwebtoken:jjwt-jackson", 'jjwt.jackson') + automaticModule("com.jcraft:jsch", 'jsch') + automaticModule("org.quartz-scheduler:quartz", 'quartz') + automaticModule("org.redisson:redisson", 'redisson') automaticModule("org.springframework.retry:spring-retry", 'spring.retry') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } diff --git a/unicorn-security/src/main/java/module-info.java b/unicorn-security/src/main/java/module-info.java index 9f94cc8e7..bc11fd87b 100644 --- a/unicorn-security/src/main/java/module-info.java +++ b/unicorn-security/src/main/java/module-info.java @@ -14,19 +14,19 @@ requires spring.websocket; requires transitive spring.rabbit; requires transitive spring.retry; - requires com.mzt.logapi; + requires bizlog.sdk; requires captcha; requires com.fasterxml.jackson.datatype.jsr310; requires com.github.oshi; - requires com.wf.captcha; - requires ch.ethz.ssh2; + requires easy.captcha; + requires ganymed.ssh2; requires transitive io.netty.common; requires transitive org.apache.tomcat.embed.websocket; - requires transitive io.jsonwebtoken.api; - requires transitive io.jsonwebtoken.impl; - requires com.jcraft.jsch; + requires transitive jjwt.api; + requires transitive jjwt.impl; + requires jsch; requires transitive org.apache.commons.io; - requires transitive org.quartz; + requires transitive quartz; provides com.anji.captcha.service.CaptchaCacheService with com.lwohvye.sys.modules.security.service.CaptchaCacheServiceRedisImpl; @@ -60,7 +60,7 @@ exports com.lwohvye.sys.modules.system.event; exports com.lwohvye.sys.modules.system.rest to spring.beans, spring.aop, spring.web; exports com.lwohvye.sys.modules.system.service; - exports com.lwohvye.sys.modules.system.service.impl to spring.beans, spring.context, spring.aop, cn.hutool; + exports com.lwohvye.sys.modules.system.service.impl to spring.beans, spring.context, spring.aop, hutool.all; exports com.lwohvye.sys.modules.system.service.version to spring.beans; exports com.lwohvye.sys.modules.system.service.local; exports com.lwohvye.sys.modules.system.service.mapstruct; diff --git a/unicorn-starter/pom.xml b/unicorn-starter/pom.xml index c61fb8b90..a0eefb64b 100644 --- a/unicorn-starter/pom.xml +++ b/unicorn-starter/pom.xml @@ -32,8 +32,8 @@ 19 3.x-SNAPSHOT - 18 - 1.18.25 + 19 + 1.18.26 1.5.3.Final 3.29.2-GA 5.2.0 diff --git a/unicorn-starter/src/main/java/module-info.java b/unicorn-starter/src/main/java/module-info.java index 4dc8b5c8a..c6e6e90bf 100644 --- a/unicorn-starter/src/main/java/module-info.java +++ b/unicorn-starter/src/main/java/module-info.java @@ -1,8 +1,8 @@ @SuppressWarnings({"requires-automatic", "requires-transitive-automatic"}) module lwohvye.unicorn.starter { requires lwohvye.unicorn.system; - requires lwohvye.unicorn.tp_tools; - requires lwohvye.unicorn.cd_generator; + requires lwohvye.unicorn.tp.tools; + requires lwohvye.unicorn.code.gen; requires org.apache.httpcomponents.httpcore; requires org.apache.httpcomponents.httpclient; requires kotlin.stdlib; diff --git a/unicorn-sys-api/build.gradle b/unicorn-sys-api/build.gradle index 4d404e4d2..349112dff 100644 --- a/unicorn-sys-api/build.gradle +++ b/unicorn-sys-api/build.gradle @@ -58,7 +58,7 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') } diff --git a/unicorn-tp-tools/build.gradle b/unicorn-tp-tools/build.gradle index 885984f07..74cde717e 100644 --- a/unicorn-tp-tools/build.gradle +++ b/unicorn-tp-tools/build.gradle @@ -62,9 +62,9 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("org.redisson:redisson", 'org.redisson') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("org.redisson:redisson", 'redisson') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') module('org.eclipse.angus:jakarta.mail', 'jakarta.mail', '1.0.0') { uses('jakarta.mail.util.StreamProvider') } diff --git a/valentine-search/pom.xml b/valentine-search/pom.xml index e7af4730a..e1d401dea 100644 --- a/valentine-search/pom.xml +++ b/valentine-search/pom.xml @@ -33,7 +33,7 @@ 19 3.x-SNAPSHOT 19 - 1.18.25 + 1.18.26 1.5.3.Final 5.0.0 1.6.6 diff --git a/valentine-starter/build.gradle b/valentine-starter/build.gradle index 5e21d01ca..6e67c35eb 100644 --- a/valentine-starter/build.gradle +++ b/valentine-starter/build.gradle @@ -33,18 +33,18 @@ dependencies { extraJavaModuleInfo { failOnMissingModuleInfo.set(false) - automaticModule("io.github.mouzt:bizlog-sdk", 'com.mzt.logapi') - automaticModule("com.github.whvcse:easy-captcha", 'com.wf.captcha') - automaticModule("ch.ethz.ganymed:ganymed-ssh2", 'ch.ethz.ssh2') - automaticModule("cn.hutool:hutool-all", 'cn.hutool') - automaticModule("io.jsonwebtoken:jjwt-api", 'io.jsonwebtoken.api') - automaticModule("io.jsonwebtoken:jjwt-impl", 'io.jsonwebtoken.impl') - automaticModule("io.jsonwebtoken:jjwt-jackson", 'io.jsonwebtoken.jackson') - automaticModule("com.jcraft:jsch", 'com.jcraft.jsch') - automaticModule("org.quartz-scheduler:quartz", 'org.quartz') - automaticModule("org.redisson:redisson", 'org.redisson') + automaticModule("io.github.mouzt:bizlog-sdk", 'bizlog.sdk') + automaticModule("com.github.whvcse:easy-captcha", 'easy.captcha') + automaticModule("ch.ethz.ganymed:ganymed-ssh2", 'ganymed.ssh2') + automaticModule("cn.hutool:hutool-all", 'hutool.all') + automaticModule("io.jsonwebtoken:jjwt-api", 'jjwt.api') + automaticModule("io.jsonwebtoken:jjwt-impl", 'jjwt.impl') + automaticModule("io.jsonwebtoken:jjwt-jackson", 'jjwt.jackson') + automaticModule("com.jcraft:jsch", 'jsch') + automaticModule("org.quartz-scheduler:quartz", 'quartz') + automaticModule("org.redisson:redisson", 'redisson') automaticModule("org.springframework.retry:spring-retry", 'spring.retry') - automaticModule("net.coobird:thumbnailator", 'net.coobird.thumbnailator') + automaticModule("net.coobird:thumbnailator", 'thumbnailator') automaticModule("org.jetbrains.kotlin:kotlin-stdlib-common", 'kotlin.stdlib.common') automaticModule("org.jetbrains.kotlinx:kotlinx-coroutines-core", 'kotlinx.coroutines.core') automaticModule("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm", 'kotlinx.coroutines.core.jvm') diff --git a/valentine-starter/src/main/java/module-info.java b/valentine-starter/src/main/java/module-info.java index 45311a2cc..6abd2b6d8 100644 --- a/valentine-starter/src/main/java/module-info.java +++ b/valentine-starter/src/main/java/module-info.java @@ -8,7 +8,7 @@ requires jakarta.mail; requires jakarta.activation; requires spring.retry; - requires com.mzt.logapi; + requires bizlog.sdk; requires kotlin.stdlib; requires kotlinx.coroutines.core.jvm; requires org.apache.logging.log4j; From 7cdcfe6882c33e8a0daa1243f7f3dd88da224237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Tue, 14 Feb 2023 11:23:34 +0800 Subject: [PATCH 06/15] change publish plugin --- build.gradle | 23 ++++++++++-------- .../com.lwohvye.java-conventions.gradle | 18 +------------- unicorn-code-gen/build.gradle | 24 +++++++++++++++++++ unicorn-core/build.gradle | 24 +++++++++++++++++++ unicorn-logging/build.gradle | 24 +++++++++++++++++++ unicorn-reactive/build.gradle | 24 +++++++++++++++++++ unicorn-security/build.gradle | 24 +++++++++++++++++++ unicorn-sys-api/build.gradle | 24 +++++++++++++++++++ unicorn-tp-tools/build.gradle | 24 +++++++++++++++++++ 9 files changed, 182 insertions(+), 27 deletions(-) diff --git a/build.gradle b/build.gradle index 8ec1ff94a..d0d59d72d 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ buildscript { } } dependencies { - classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0" classpath "org.gradlex:extra-java-module-info:1.2.1" } } @@ -22,7 +21,7 @@ plugins { id 'org.springframework.boot' // 主要是定义了这个,定义了SpringBoot的Version相关,并提供了application, bootJar, bootBuildImage这些Task // 在parent root执行Task,会同步执行sub project的Task,比如执行了bootJar,那会执行subPro的bootJar(若其中没有该Task会ignore) id 'signing' - id 'io.codearte.nexus-staging' version '0.30.0' + id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' } ext.sharedManifest = manifest { @@ -91,8 +90,8 @@ publishing { url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' properties = [ myProp : "chaste unicorn", - "spring-boot.version" : "3.0.0", - "project.core.version": "4.0.0" + "spring-boot.version" : "${springBootVersion}", + "project.core.version": "${version}" ] licenses { license { @@ -112,7 +111,7 @@ publishing { connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' - tag = 'unicorn-v4.0.0-SNAPSHOT' + tag = "unicorn-v${version}-SNAPSHOT" } } } @@ -129,9 +128,13 @@ javadoc { } } -nexusStaging { - serverUrl = "https://s01.oss.sonatype.org/service/local/" - //required only for projects registered in Sonatype after 2021-02-24 -// packageGroup = "org.mycompany.myproject" //optional if packageGroup == project.getGroup() -// stagingProfileId = "yourStagingProfileId" //when not defined will be got from server using "packageGroup" +nexusPublishing { + repositories { + sonatype { + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + username = ossrhUsername // defaults to project.properties["myNexusUsername"] + password = ossrhPassword // defaults to project.properties["myNexusPassword"] + } + } } diff --git a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle index 342b43282..7003421d6 100644 --- a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle +++ b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle @@ -21,7 +21,7 @@ repositories { } group = 'com.lwohvye' -version = '4.0.0-SNAPSHOT' +version = '4.0.0-alpha' java.sourceCompatibility = JavaVersion.VERSION_19 ext { @@ -33,22 +33,6 @@ java { withSourcesJar() } -publishing { - repositories { - maven { - name = "OSSRH" - // change URLs to point to your repos, e.g. http://my.org/repo - def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" - def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - credentials { - username = ossrhUsername - password = ossrhPassword - } - } - } -} - tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs += '--enable-preview' diff --git a/unicorn-code-gen/build.gradle b/unicorn-code-gen/build.gradle index 49ac8e810..5d65dec6b 100644 --- a/unicorn-code-gen/build.gradle +++ b/unicorn-code-gen/build.gradle @@ -42,6 +42,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Code Generator' + description = 'Server and Web Code Generator' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index 732cb8cd8..da4768ce2 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -55,6 +55,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Core' + description = 'Common module with BaseConfig, Utils, QueryAnno and so on' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-logging/build.gradle b/unicorn-logging/build.gradle index a0fb3965b..ab0c6aad6 100644 --- a/unicorn-logging/build.gradle +++ b/unicorn-logging/build.gradle @@ -42,6 +42,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Log Collector' + description = 'Logging module with API for store and retrieve' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-reactive/build.gradle b/unicorn-reactive/build.gradle index eb58633c2..fbad33ba9 100644 --- a/unicorn-reactive/build.gradle +++ b/unicorn-reactive/build.gradle @@ -46,6 +46,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Reactive Core' + description = 'Core module extend for WebFlux' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index 55edd1716..033984eb0 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -48,6 +48,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Security Control' + description = 'Security module with Control and Management' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-sys-api/build.gradle b/unicorn-sys-api/build.gradle index 349112dff..51bd727c7 100644 --- a/unicorn-sys-api/build.gradle +++ b/unicorn-sys-api/build.gradle @@ -42,6 +42,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn Sys Domain' + description = 'Domain data for Security module' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } diff --git a/unicorn-tp-tools/build.gradle b/unicorn-tp-tools/build.gradle index 74cde717e..47f9bdbdf 100644 --- a/unicorn-tp-tools/build.gradle +++ b/unicorn-tp-tools/build.gradle @@ -42,6 +42,30 @@ publishing { fromResolutionResult() } } + pom { + name = 'Unicorn 3rd Tools' + description = 'Tools and Third Party Integration' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p.git' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'lWoHvYe' + name = '王红岩(lWoHvYe)' + email = 'lWoHvYe@outlook.com' + url = 'https://www.lwohvye.com' + } + } + scm { + connection = 'scm:git:git://github.com/WHY-lWoHvYe/valentine-p2p.git' + developerConnection = 'scm:git:ssh://github.com/WHY-lWoHvYe/valentine-p2p.git' + url = 'https://github.com/WHY-lWoHvYe/valentine-p2p/tree/main' + } + } } } } From bdc05bd3fbc479c8d3dcf81c5834d7ba6d9384c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Thu, 16 Feb 2023 22:20:45 +0800 Subject: [PATCH 07/15] - fixed javadoc issue - modify some configurations --- build.gradle | 11 ++++++++--- .../main/groovy/com.lwohvye.java-conventions.gradle | 6 ------ unicorn-code-gen/build.gradle | 5 ++++- unicorn-core/build.gradle | 6 +++++- unicorn-logging/build.gradle | 5 ++++- unicorn-reactive/build.gradle | 5 ++++- unicorn-security/build.gradle | 5 ++++- .../sys/modules/system/repository/RoleRepository.java | 5 ----- .../sys/modules/system/repository/UserRepository.java | 5 ----- .../sys/modules/system/service/IResourceService.java | 4 ++-- unicorn-sys-api/build.gradle | 5 ++++- unicorn-tp-tools/build.gradle | 5 ++++- 12 files changed, 39 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index d0d59d72d..f22327c1e 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,8 @@ subprojects { options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('encoding', 'UTF-8') options.addStringOption('charSet', 'UTF-8') + options.addBooleanOption('-enable-preview', true) + options.addStringOption('-release', '19') // Add support for custom tag options.addStringOption('tag', 'date:a:Init Date:') options.addStringOption('tag', 'author:a:Major Contributor:') @@ -119,7 +121,10 @@ publishing { } signing { - sign publishing.publications.mavenJava + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } javadoc { @@ -133,8 +138,8 @@ nexusPublishing { sonatype { nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) - username = ossrhUsername // defaults to project.properties["myNexusUsername"] - password = ossrhPassword // defaults to project.properties["myNexusPassword"] + username.set(System.getenv('OSSRH_USERNAME') ?: providers.systemProperty("ossrhUsername").orElse("").forUseAtConfigurationTime()) + password.set(System.getenv('OSSRH_PASSWORD') ?: providers.systemProperty("ossrhPassword").orElse("").forUseAtConfigurationTime()) } } } diff --git a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle index 7003421d6..308c2f6d7 100644 --- a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle +++ b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle @@ -8,7 +8,6 @@ plugins { } repositories { - mavenLocal() mavenCentral() flatDir { dirs "$rootProject.projectDir/ex-lib" @@ -24,11 +23,6 @@ group = 'com.lwohvye' version = '4.0.0-alpha' java.sourceCompatibility = JavaVersion.VERSION_19 -ext { - ossrhUsername = System.getenv('OSSRH_USERNAME') ?: ossrhUsername ?: '' - ossrhPassword = System.getenv('OSSRH_PASSWORD') ?: ossrhPassword ?: '' -} - java { withSourcesJar() } diff --git a/unicorn-code-gen/build.gradle b/unicorn-code-gen/build.gradle index 5d65dec6b..b0563a7b1 100644 --- a/unicorn-code-gen/build.gradle +++ b/unicorn-code-gen/build.gradle @@ -71,7 +71,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaCodeGen + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index da4768ce2..1f0d8f7b6 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -84,7 +84,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaCore + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { @@ -114,6 +117,7 @@ dependencies { implementation "net.logstash.logback:logstash-logback-encoder:$logstashVersion" api "net.coobird:thumbnailator:$thumbnailatorVersion" api 'org.jetbrains:annotations:23.0.0' + api 'io.vavr:vavr:0.10.4' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnlyApi "org.projectlombok:lombok:${lombokVersion}" compileOnlyApi "org.mapstruct:mapstruct-processor:$mapstructVersion" diff --git a/unicorn-logging/build.gradle b/unicorn-logging/build.gradle index ab0c6aad6..46120d1b4 100644 --- a/unicorn-logging/build.gradle +++ b/unicorn-logging/build.gradle @@ -71,7 +71,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaLog + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { diff --git a/unicorn-reactive/build.gradle b/unicorn-reactive/build.gradle index fbad33ba9..88b5270be 100644 --- a/unicorn-reactive/build.gradle +++ b/unicorn-reactive/build.gradle @@ -75,7 +75,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaReact + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index 033984eb0..031e25e9e 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -77,7 +77,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaSecurity + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/RoleRepository.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/RoleRepository.java index a9421c0ef..fa9c575ed 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/RoleRepository.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/RoleRepository.java @@ -36,11 +36,6 @@ public interface RoleRepository extends JpaRepository, JpaSpecificat /** * 重写查询所有的方法,指定EntityGraph。查询就从多条查询变成了一条关联查询。但分页会变成内存分页。实际业务中,数据量大时不建议使用 * 在多对多的关系中,若存在关联关系,但另一方已经不在了,在总查询后,还会有对不存在的那条的单查询(根据id查实体)。这时就会报错不存在。因此需要把关联表维护好,不要出现脏数据 - * - * @param spec - * @param pageable - * @return org.springframework.data.domain.Page - * @date 2021/11/6 12:09 上午 */ // An entity graph can be used as a fetch or a load graph. // If a fetch graph is used, only the attributes specified by the entity graph will be treated as FetchType.EAGER. All other attributes will be lazy. diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/UserRepository.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/UserRepository.java index 6088021b5..84ebcca31 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/UserRepository.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/repository/UserRepository.java @@ -48,11 +48,6 @@ public interface UserRepository extends JpaRepository, JpaSpecificat * 若配置了Graph图,则查询会变成查满足条件的所有。然后内存分页。故分页类查询不建议使用。下面两个只作为存档。 * 但一些根据特定条件只过滤出很少记录的,可以考虑使用,比如这里的根据id、name等的查询 * 这个感觉跟MyBatis中配置的多对一的association标签,一对多的collection标签差不多,感觉很美好,但内存分页是硬伤 - * - * @param spec - * @param pageable - * @return org.springframework.data.domain.Page - * @date 2021/11/9 10:05 下午 */ //@Override // @EntityGraph(value = "User-Details") // 11-26,这个加入意义不大,且对查询注解的Test造成mistake,故注释掉 diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/service/IResourceService.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/service/IResourceService.java index 122275ac5..4ebeb51a6 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/service/IResourceService.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/service/IResourceService.java @@ -40,7 +40,7 @@ public interface IResourceService extends BaseService { * * @param criteria 条件 * @param pageable 分页参数 - * @return Map + * @return Map */ Map queryAll(ResourceQueryCriteria criteria, Pageable pageable); @@ -48,7 +48,7 @@ public interface IResourceService extends BaseService { * 查询所有数据不分页 * * @param criteria 条件参数 - * @return List + * @return List */ List queryAll(ResourceQueryCriteria criteria); diff --git a/unicorn-sys-api/build.gradle b/unicorn-sys-api/build.gradle index 51bd727c7..49f0eba9f 100644 --- a/unicorn-sys-api/build.gradle +++ b/unicorn-sys-api/build.gradle @@ -71,7 +71,10 @@ publishing { } signing { - sign publishing.publications.mavenJavaSysApi + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { diff --git a/unicorn-tp-tools/build.gradle b/unicorn-tp-tools/build.gradle index 47f9bdbdf..99a643517 100644 --- a/unicorn-tp-tools/build.gradle +++ b/unicorn-tp-tools/build.gradle @@ -71,7 +71,10 @@ publishing { } signing { - sign publishing.publications.mavenJava3rdTool + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } } dependencies { From d23d6f96ec03fa1ac342073f80ccf2e7baf45c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Thu, 16 Feb 2023 23:07:00 +0800 Subject: [PATCH 08/15] =?UTF-8?q?`@snippet=20:=20`=20=20=E5=86=92=E5=8F=B7?= =?UTF-8?q?=E5=88=AB=E5=BF=98=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/ApiVersionRequestMappingHandlerMapping.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/common/handler/ApiVersionRequestMappingHandlerMapping.java b/unicorn-security/src/main/java/com/lwohvye/sys/common/handler/ApiVersionRequestMappingHandlerMapping.java index 6b28c0123..385cfe8af 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/common/handler/ApiVersionRequestMappingHandlerMapping.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/common/handler/ApiVersionRequestMappingHandlerMapping.java @@ -30,7 +30,7 @@ * ... * 自定义匹配的处理器 * 这里用了JDK 18的一个特性:JEP 413: Code Snippets in Java API Documentation - * {@snippet + * {@snippet : * * @ApiVersion * @GetMapping("/{version}/test1") // 这种在`ApiVersion`中不指定version的,适合各个版本,因为默认值是1所以是 [1+ @@ -38,14 +38,12 @@ * public String test1(){ * return "test 1"; * } - *

* @ApiVersion * @GetMapping("/{ver}/test2") // 这里的占位符不只限`version` * @ResponseBody * public String test2(){ * return "test 2"; * } - *

* @ApiVersion(3) * @GetMapping("/{version}/test3") // 这种指定了version的,表示的从这个版本开始 [3+ * @ResponseBody From 2ee506a29b280e68a29f32cda86720a8f7ba7ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Fri, 17 Feb 2023 08:45:41 +0800 Subject: [PATCH 09/15] update configure structure --- build.gradle | 8 ----- .../com.lwohvye.java-conventions.gradle | 8 +++++ unicorn-code-gen/build.gradle | 8 ----- unicorn-core/build.gradle | 8 ----- .../java/com/lwohvye/core/utils/JDKUtils.java | 29 +++++++++++++++++-- unicorn-logging/build.gradle | 8 ----- unicorn-reactive/build.gradle | 8 ----- unicorn-security/build.gradle | 8 ----- unicorn-sys-api/build.gradle | 8 ----- unicorn-tp-tools/build.gradle | 8 ----- 10 files changed, 35 insertions(+), 66 deletions(-) diff --git a/build.gradle b/build.gradle index f22327c1e..7f9706cb3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.springframework.boot' // 主要是定义了这个,定义了SpringBoot的Version相关,并提供了application, bootJar, bootBuildImage这些Task // 在parent root执行Task,会同步执行sub project的Task,比如执行了bootJar,那会执行subPro的bootJar(若其中没有该Task会ignore) - id 'signing' id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' } @@ -120,13 +119,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - javadoc { if (JavaVersion.current().isJava9Compatible()) { options.addBooleanOption('html5', true) diff --git a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle index 308c2f6d7..ab4c44c1e 100644 --- a/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle +++ b/buildSrc/src/main/groovy/com.lwohvye.java-conventions.gradle @@ -5,6 +5,7 @@ plugins { id 'java-library' id 'maven-publish' + id 'signing' } repositories { @@ -27,6 +28,13 @@ java { withSourcesJar() } +signing { + required { !version.endsWith("-SNAPSHOT") } + publishing.publications.configureEach { + sign it + } +} + tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs += '--enable-preview' diff --git a/unicorn-code-gen/build.gradle b/unicorn-code-gen/build.gradle index b0563a7b1..32a4c8e96 100644 --- a/unicorn-code-gen/build.gradle +++ b/unicorn-code-gen/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } description = '代码生成模块' @@ -70,13 +69,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api project(':unicorn-core') api 'org.springframework.boot:spring-boot-starter-freemarker' diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index 1f0d8f7b6..c464ed008 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -7,7 +7,6 @@ plugins { id 'com.lwohvye.java-conventions' // id 'extra-java-module-info' // apply my own plugin written in buildSrc id 'org.gradlex.extra-java-module-info' - id 'signing' // id 'org.springframework.boot' } @@ -83,13 +82,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api platform(SpringBootPlugin.BOM_COORDINATES) api 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java index 72f37c159..fec68b789 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java @@ -16,11 +16,17 @@ package com.lwohvye.core.utils; -import java.lang.invoke.*; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.nio.ByteOrder; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; import static java.lang.invoke.MethodType.methodType; @@ -49,6 +55,7 @@ public class JDKUtils { public static final boolean BIG_ENDIAN; public static final boolean UNSAFE_SUPPORT; + public static final boolean VECTOR_SUPPORT; // GraalVM not support // Android not support @@ -136,6 +143,24 @@ public class JDKUtils { FIELD_STRING_VALUE_OFFSET = -1; } + var vector_support = false; + try { + if (JVM_VERSION >= 17) { + // the following is a way to get inputArgs + var factorClass = Class.forName("java.lang.management.ManagementFactory"); + var runtimeMXBeanClass = Class.forName("java.lang.management.RuntimeMXBean"); + var getRuntimeMXBean = factorClass.getMethod("getRuntimeMXBean"); + var runtimeMXBean = getRuntimeMXBean.invoke(null); + var getInputArguments = runtimeMXBeanClass.getMethod("getInputArguments"); + var inputArguments = (List) getInputArguments.invoke(runtimeMXBean); +// vector_support = inputArguments.contains("--add-modules=jdk.incubator.vector"); + vector_support = true; + } + } catch (Throwable ignored) { + initErrorLast = ignored; + } + VECTOR_SUPPORT = vector_support; + boolean unsafeSupport; unsafeSupport = ((Predicate) o -> { try { diff --git a/unicorn-logging/build.gradle b/unicorn-logging/build.gradle index 46120d1b4..f7a7e154c 100644 --- a/unicorn-logging/build.gradle +++ b/unicorn-logging/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } description = '日志收集模块' @@ -70,13 +69,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api project(':unicorn-core') annotationProcessor "org.projectlombok:lombok:${lombokVersion}" diff --git a/unicorn-reactive/build.gradle b/unicorn-reactive/build.gradle index 88b5270be..1b67c61c7 100644 --- a/unicorn-reactive/build.gradle +++ b/unicorn-reactive/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } ext { @@ -74,13 +73,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api(project(':unicorn-core')) { // 括号里是Groovy的语法,定义map diff --git a/unicorn-security/build.gradle b/unicorn-security/build.gradle index 031e25e9e..6866038b4 100644 --- a/unicorn-security/build.gradle +++ b/unicorn-security/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } description = '权限管理模块' @@ -76,13 +75,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api project(':unicorn-sys-api') api('org.springframework.boot:spring-boot-starter-websocket') diff --git a/unicorn-sys-api/build.gradle b/unicorn-sys-api/build.gradle index 49f0eba9f..3a726d95d 100644 --- a/unicorn-sys-api/build.gradle +++ b/unicorn-sys-api/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } description = '权限基础模块' @@ -70,13 +69,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api project(':unicorn-core') annotationProcessor "org.projectlombok:lombok:${lombokVersion}" diff --git a/unicorn-tp-tools/build.gradle b/unicorn-tp-tools/build.gradle index 99a643517..19e35b1e4 100644 --- a/unicorn-tp-tools/build.gradle +++ b/unicorn-tp-tools/build.gradle @@ -5,7 +5,6 @@ plugins { id 'com.lwohvye.java-conventions' id 'org.gradlex.extra-java-module-info' - id 'signing' } description = '3rd工具模块' @@ -70,13 +69,6 @@ publishing { } } -signing { - required { !version.endsWith("-SNAPSHOT") } - publishing.publications.configureEach { - sign it - } -} - dependencies { api project(':unicorn-core') api 'org.springframework.boot:spring-boot-starter-mail' From eb54f7424d53a371fc0af5851e7da448f1971902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Wed, 22 Feb 2023 13:26:36 +0800 Subject: [PATCH 10/15] =?UTF-8?q?MethodHandle=EF=BC=8C=E6=B3=A8=E6=84=8F?= =?UTF-8?q?=E5=AF=B9=E5=8F=AF=E5=8F=98=E5=8F=82=E6=95=B0=E7=9A=84=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E5=8F=AF=E8=83=BD=E4=BC=9A=E5=AF=BC=E8=87=B4=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.properties | 18 +----- unicorn-core/build.gradle | 2 +- .../context/CycleAvoidingMappingContext.java | 29 ++++----- .../java/com/lwohvye/core/utils/JDKUtils.java | 63 ++++++++++++++++++- .../RabbitBusinessMsgConsumerService.java | 18 +++++- ...ntiationTracingBeanPostProcessor4Core.java | 8 +-- .../RabbitMQDelayMsgConsumerService.java | 24 +++++-- .../service/RabbitMQSPMsgConsumerService.java | 16 ++++- .../modules/system/domain/vo/ResourceVo.java | 16 ++--- .../src/main/resources/config/application.yml | 4 +- 10 files changed, 140 insertions(+), 58 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d28f17331..42defcc94 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,22 +1,6 @@ -# -# Copyright (c) 2023. lWoHvYe(Hongyan Wang) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/unicorn-core/build.gradle b/unicorn-core/build.gradle index c464ed008..d6f5aa707 100644 --- a/unicorn-core/build.gradle +++ b/unicorn-core/build.gradle @@ -108,7 +108,7 @@ dependencies { api 'com.github.ben-manes.caffeine:caffeine' implementation "net.logstash.logback:logstash-logback-encoder:$logstashVersion" api "net.coobird:thumbnailator:$thumbnailatorVersion" - api 'org.jetbrains:annotations:23.0.0' + api 'org.jetbrains:annotations:24.0.0' api 'io.vavr:vavr:0.10.4' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnlyApi "org.projectlombok:lombok:${lombokVersion}" diff --git a/unicorn-core/src/main/java/com/lwohvye/core/context/CycleAvoidingMappingContext.java b/unicorn-core/src/main/java/com/lwohvye/core/context/CycleAvoidingMappingContext.java index 139be368f..01522dca1 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/context/CycleAvoidingMappingContext.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/context/CycleAvoidingMappingContext.java @@ -6,12 +6,12 @@ package com.lwohvye.core.context; import cn.hutool.core.util.ReflectUtil; +import com.lwohvye.core.utils.JDKUtils; import lombok.SneakyThrows; import org.mapstruct.BeforeMapping; import org.mapstruct.Context; import org.mapstruct.MappingTarget; import org.mapstruct.TargetType; -import org.springframework.util.ReflectionUtils; import java.lang.reflect.Field; import java.util.IdentityHashMap; @@ -39,28 +39,28 @@ public class CycleAvoidingMappingContext { @BeforeMapping public T getMappedInstance(Object source, @TargetType Class targetType) { - var obj = knownInstances.get(source); + var originalObj = knownInstances.get(source); // 判断类型 - if (targetType.isInstance(obj)) + if (targetType.isInstance(originalObj)) // 是该类型进行转换 - return targetType.cast(obj); + return targetType.cast(originalObj); else // 不是该类型时,一般是small类型,需要做source -> T的显示转换(非强转) - return genT(targetType, obj); + return genT(targetType, originalObj); } /** * smallDto中的属性,必须为原始侧的子集 * - * @param targetType Class for smallDto - * @param obj 原始侧Dto + * @param targetType Class for smallDto + * @param originalObj 原始侧Dto * @return T smallDto的实例 * @date 2021/11/10 12:38 上午 */ @SneakyThrows - private T genT(Class targetType, Object obj) { + private T genT(Class targetType, Object originalObj) { // obj为null时,直接返回 - if (Objects.isNull(obj)) + if (Objects.isNull(originalObj)) return null; // var t = ReflectUtil.newInstance(targetType); @@ -69,15 +69,16 @@ private T genT(Class targetType, Object obj) { // targetType.getDeclaredFields() 可以获取本类中的所有域,不包括从超类继承的 // 所以还是使用ReflectUtil.getFields(targetType),获取全部的域,包括从超类继承的 for (Field field : ReflectUtil.getFields(targetType)) { + JDKUtils.copyFieldVal(originalObj, t, field); // 获取不到属性会报错哦。并且需注意,从obj取时,要使用fieldName,因为field是t中的属性 - var oField = ReflectionUtils.findField(obj.getClass(), field.getName()); - if (Objects.nonNull(oField) && oField.trySetAccessible() && field.trySetAccessible()) - field.set(t, oField.get(obj)); +// var oField = ReflectionUtils.findField(orginalClass, field.getName()); +// if (Objects.nonNull(oField) && oField.trySetAccessible() && field.trySetAccessible()) +// field.set(t, oField.get(originalObj)); // 下面的反射,底层还是 field.get()获取属性、field.set()设置属性 - // ReflectUtil.setFieldValue(t, field, ReflectUtil.getFieldValue(obj, field.getName())); + // ReflectUtil.setFieldValue(t, field, ReflectUtil.getFieldValue(originalObj, field.getName())); } // 不是该类型,通过先转成Json,再转成另一实体实现。这种不一致的一般是用xxxSmallDTO时。这是不使用反射时,另一种处理方式 - // return JsonUtils.toJavaObject(obj, targetType); + // return JsonUtils.toJavaObject(originalObj, targetType); return t; } diff --git a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java index fec68b789..982ee066f 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java @@ -16,11 +16,15 @@ package com.lwohvye.core.utils; +import com.lwohvye.core.exception.UtilsException; + import java.lang.invoke.LambdaMetafactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.nio.ByteOrder; +import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiFunction; @@ -327,7 +331,7 @@ public static char[] getCharArray(String str) { /** * JDK 8开始支持Lambda,为了方便将一个Method映射为一个Lambda Function,避免反射开销。 - * java.invoke.LambdaMetafactory 可以实现这一功能,但这个也受限于可见性的限制,也就是说不能调用私有方法。 + * java.invoke.LambdaMetaFactory 可以实现这一功能,但这个也受限于可见性的限制,也就是说不能调用私有方法。 * 有一个技巧,结合Unsafe,可以在不同版本的JDK都能构造一个Trusted MethodHandles.Lookup来绕开可见性的限制,调用任何JDK内部方法。 * * @param objectClass @@ -371,6 +375,63 @@ public static MethodHandles.Lookup trustedLookup(Class objectClass) { return IMPL_LOOKUP.in(objectClass); } + /** + * 属性拷贝,但使用其他lookup时存在导致♻️依赖的隐患(使用IMPL_LOOKUP后解决),在这点上不如Field.set/get, + * 且在 field.trySetAccessible()后,跳过了accessCheck,未必效率就低很多 + * + * @param originalObj originalInstance + * @param t targetInstance + * @param field field to operate + * @date 2023/2/22 9:16 AM + */ + public static void copyFieldVal(Object originalObj, T t, Field field) throws IllegalAccessException, NoSuchFieldException { + var targetVarHandle = IMPL_LOOKUP.unreflectVarHandle(field); + var originalVarHandle = IMPL_LOOKUP.findVarHandle(originalObj.getClass(), field.getName(), field.getType()); + targetVarHandle.set(t, originalVarHandle.get(originalObj)); + } + + /** + * 只支持简单无参调用,invoke + * + * @date 2023/2/22 1:21 PM + */ + public static T invokeMethod(Object obj, String methodName, Class rType) { + var mt = MethodType.methodType(rType); + try { + var methodHandle = IMPL_LOOKUP.findVirtual(obj.getClass(), methodName, mt); + var result = methodHandle.invoke(obj); + return (T) result; + } catch (Throwable e) { + throw new UtilsException("invoke error: " + e.getMessage()); + } + } + + /** + * MethodType的pTypes需要与目标方法签名一致(不支持向上/向下转型,比如用Integer去获取入参为Number的方法是不允许的,同样用Number去获取入参为Integer的方法也不行。这个还能理解), + * rtype需要与目标方法的返回值一致(不允许向上/向下转型。不允许向下很容易理解,为何要不允许向上转型,有点不理解)。以上并不是下面问题的原因 + * 该方法的使用场景很有限,因为虽然invoke的入参是可变参数,但本方法入参中的可变参数会被转成数组,把数组传给invoke与本方法的原入参是不一样的 (原来会是包含各种类型的可变参数,转换后变成单纯的Object[]),也就导致了与直接调用存在差异 + * 这种感觉主要是底层的解析逻辑,当考虑做为中间层传递这种可变参数时,⚠️可能会出现问题 + * + * @param obj callInstance + * @param methodName invokeMethodName + * @param rType returnType + * @param params args + * @return T + * @date 2023/2/22 11:00 AM + */ + @Deprecated(forRemoval = true) + public static T invokeMethod(Object obj, String methodName, Class rType, Object... params) { + var pTypes = Arrays.stream(params).map(Object::getClass).toArray(Class[]::new); + var mt = MethodType.methodType(rType, pTypes); + try { + var methodHandle = IMPL_LOOKUP.findVirtual(obj.getClass(), methodName, mt); + var result = params.length != 0 ? methodHandle.invoke(obj, params) : methodHandle.invoke(obj); + return (T) result; + } catch (Throwable e) { + throw new UtilsException("invoke error: " + e.getMessage()); + } + } + // region access field public static void setField(Object obj, Object value, Field field) throws ReflectiveOperationException { if (obj == null) { diff --git a/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitBusinessMsgConsumerService.java b/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitBusinessMsgConsumerService.java index a66d1dca9..deaff3b9d 100644 --- a/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitBusinessMsgConsumerService.java +++ b/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitBusinessMsgConsumerService.java @@ -16,7 +16,7 @@ package com.lwohvye.log.rabbitmq; -import cn.hutool.core.util.ReflectUtil; +import com.lwohvye.core.exception.UtilsException; import com.lwohvye.core.utils.rabbitmq.AmqpMsgEntity; import com.lwohvye.core.utils.rabbitmq.YRabbitAbstractConsumer; import com.lwohvye.log.service.local.MultiLogService; @@ -28,6 +28,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + @Slf4j @Component public class RabbitBusinessMsgConsumerService extends YRabbitAbstractConsumer { @@ -35,6 +38,8 @@ public class RabbitBusinessMsgConsumerService extends YRabbitAbstractConsumer { @Autowired private MultiLogService multiLogService; + private final MethodHandles.Lookup lookup = MethodHandles.lookup(); + @Autowired public void setRedissonClient(RedissonClient redissonClient) { super.redissonClient = redissonClient; @@ -48,8 +53,15 @@ public void setRedissonClient(RedissonClient redissonClient) { public void handle(String messageStr) { baseConsumer(messageStr, null, null, msgEntity -> { var extraData = msgEntity.getExtraData(); - if (StringUtils.hasText(extraData)) - ReflectUtil.invoke(multiLogService, extraData, msgEntity.getMsgType(), msgEntity.getMsgData(), "Typical Business Operate"); + if (StringUtils.hasText(extraData)) { + try { + var mt = MethodType.methodType(void.class, String.class, String.class, String.class); + var methodHandle = lookup.findVirtual(multiLogService.getClass(), extraData, mt); + methodHandle.invoke(multiLogService, msgEntity.getMsgType(), msgEntity.getMsgData(), "Typical Business Operate"); + } catch (Throwable e) { + throw new UtilsException(e.getMessage()); + } + } return null; }, errMsg -> log.error(" Consume Msg Error, Reason: {} || Msg detail: {} ", errMsg, messageStr)); } diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/common/init/InstantiationTracingBeanPostProcessor4Core.java b/unicorn-security/src/main/java/com/lwohvye/sys/common/init/InstantiationTracingBeanPostProcessor4Core.java index a718f74de..685ce5de8 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/common/init/InstantiationTracingBeanPostProcessor4Core.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/common/init/InstantiationTracingBeanPostProcessor4Core.java @@ -15,10 +15,10 @@ */ package com.lwohvye.sys.common.init; -import cn.hutool.core.util.ReflectUtil; -import com.lwohvye.sys.modules.system.strategy.NormalUserTypeStrategy; -import com.lwohvye.sys.modules.system.service.ITerminalService; +import com.lwohvye.core.utils.JDKUtils; import com.lwohvye.core.utils.SpringContextHolder; +import com.lwohvye.sys.modules.system.service.ITerminalService; +import com.lwohvye.sys.modules.system.strategy.NormalUserTypeStrategy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationListener; @@ -46,7 +46,7 @@ public void onApplicationEvent(ContextRefreshedEvent event) { if (event.getApplicationContext().getParent() == null) {//root application context 没有parent,再执行这个. //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。这种可以参考观察者模式改造中的方式,先addCallBacks,启动后会自动执行,这里用来保留另一种方式。 var userTypeHandler = SpringContextHolder.getBean(NormalUserTypeStrategy.class); - ReflectUtil.invoke(userTypeHandler, "doInit"); + JDKUtils.invokeMethod(userTypeHandler, "doInit", void.class); var terminalClazz = ITerminalService.class; try { diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java index 18329241b..b89ac3379 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java @@ -15,12 +15,12 @@ */ package com.lwohvye.sys.modules.rabbitmq.service; -import cn.hutool.core.util.ReflectUtil; -import com.lwohvye.sys.modules.rabbitmq.config.RabbitMQConfig; -import com.lwohvye.sys.modules.system.service.local.AuthMQService; +import com.lwohvye.core.exception.UtilsException; import com.lwohvye.core.utils.MailAdapter; import com.lwohvye.core.utils.rabbitmq.AmqpMsgEntity; import com.lwohvye.core.utils.rabbitmq.YRabbitAbstractConsumer; +import com.lwohvye.sys.modules.rabbitmq.config.RabbitMQConfig; +import com.lwohvye.sys.modules.system.service.local.AuthMQService; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RedissonClient; import org.springframework.amqp.rabbit.annotation.RabbitHandler; @@ -29,6 +29,8 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.Map; @Component @@ -54,6 +56,8 @@ public class RabbitMQDelayMsgConsumerService extends YRabbitAbstractConsumer { @Autowired private AuthMQService authMQService; + private final MethodHandles.Lookup lookup = MethodHandles.lookup(); + @Autowired public void setRedissonClient(RedissonClient redissonClient) { super.redissonClient = redissonClient; @@ -64,8 +68,18 @@ public void setRedissonClient(RedissonClient redissonClient) { public void handle(String amqpMsgEntityStr) { baseConsumer(amqpMsgEntityStr, "auth", null, msgEntity -> { var extraData = msgEntity.getExtraData(); - if (StringUtils.hasText(extraData)) - ReflectUtil.invoke(authMQService, extraData, msgEntity.getMsgData()); + if (StringUtils.hasText(extraData)) { + try { + var mt = MethodType.methodType(void.class, new Class[]{String.class}); + var methodHandle = lookup.findVirtual(authMQService.getClass(), extraData, mt); + methodHandle.invoke(authMQService, msgEntity.getMsgData()); +// methodHandle.invoke(authMQService, new Object[]{msgEntity.getMsgData()}); // Cannot cast [Ljava.lang.Object; to java.lang.String +// methodHandle.invoke(new Object[]{authMQService, msgEntity.getMsgData()}); // cannot convert MethodHandle(AuthMQService,String)void to (Object[])void + // 至此,便明白了,虽然方法入参是可变参数,但传多个参数跟传一个数组近去处理方面是不一样的,暂不清楚原因 + } catch (Throwable e) { + throw new UtilsException(e.getMessage()); + } + } return null; }, errMsg -> { // reConsumeMsg(this::handle, amqpMsgEntityStr); diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQSPMsgConsumerService.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQSPMsgConsumerService.java index 9989aab35..e00a6d907 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQSPMsgConsumerService.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQSPMsgConsumerService.java @@ -16,11 +16,11 @@ package com.lwohvye.sys.modules.rabbitmq.service; -import cn.hutool.core.util.ReflectUtil; import com.lwohvye.core.config.LocalCoreConfig; -import com.lwohvye.sys.modules.security.service.UserLocalCache; +import com.lwohvye.core.exception.UtilsException; import com.lwohvye.core.utils.rabbitmq.AmqpMsgEntity; import com.lwohvye.core.utils.rabbitmq.YRabbitAbstractConsumer; +import com.lwohvye.sys.modules.security.service.UserLocalCache; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RedissonClient; import org.springframework.amqp.core.Message; @@ -30,12 +30,16 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + @Component @Slf4j public class RabbitMQSPMsgConsumerService extends YRabbitAbstractConsumer { private UserLocalCache userLocalCache; + private final MethodHandles.Lookup lookup = MethodHandles.lookup(); @Autowired // Spring循环依赖问题,可以通过将构造注入改为setter注入的方式解决(三个Map)。也可以使用@Lazy注解。还有些别的解决方式 // 这里只是做一个记录。UserCacheClean并未构成循环依赖 @@ -57,7 +61,13 @@ public void spMsgConsumer(Message message) { var extraData = msgEntity.getExtraData(); if (StringUtils.hasText(extraData)) // 这里的逻辑比较简单,首先内部已经做了忽略本实例产生的消息的逻辑。视情况可能还要做:有时需要忽略本集群产生的事件,有时需要向内部传递调用方为MQ消费者从而视情况不进行事件的扩散(虽然一般都是来自消费者的调用不做数据及事件的同步) - ReflectUtil.invoke(userLocalCache, extraData, msgEntity.getMsgData(), false); + try { + var mt = MethodType.methodType(void.class, String.class, Boolean.class); + var methodHandle = lookup.findVirtual(userLocalCache.getClass(), extraData, mt); + methodHandle.invoke(userLocalCache, msgEntity.getMsgData(), false); + } catch (Throwable e) { + throw new UtilsException(e.getMessage()); + } return null; }, s -> { // 先移除消费过的标志,再主动重新消费一下。考虑了一下,这种cancel还是交给子类,否则要额外传个Consumer进去了 diff --git a/unicorn-sys-api/src/main/java/com/lwohvye/api/modules/system/domain/vo/ResourceVo.java b/unicorn-sys-api/src/main/java/com/lwohvye/api/modules/system/domain/vo/ResourceVo.java index 4d90229f2..3a87167a1 100644 --- a/unicorn-sys-api/src/main/java/com/lwohvye/api/modules/system/domain/vo/ResourceVo.java +++ b/unicorn-sys-api/src/main/java/com/lwohvye/api/modules/system/domain/vo/ResourceVo.java @@ -18,12 +18,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.lwohvye.api.modules.system.domain.Resource; +import com.lwohvye.core.utils.JDKUtils; import lombok.Getter; import lombok.SneakyThrows; -import org.springframework.util.ReflectionUtils; import java.lang.reflect.Field; -import java.util.Objects; @Getter // 要序列化,就要把get方法放出来 public class ResourceVo { @@ -51,12 +50,13 @@ public static ResourceVo toVo(Resource resource) { // 在这里打断点,导致发起了很多打dbSearch,造成长时间停顿。不打就没问题 var vo = new ResourceVo(); var fields = ResourceVo.class.getDeclaredFields(); - for (Field field : fields) { - var rField = ReflectionUtils.findField(resource.getClass(), field.getName()); - if (Objects.nonNull(rField) && field.trySetAccessible() && rField.trySetAccessible()) - field.set(vo, rField.get(resource)); - // ReflectUtil.setFieldValue(vo, field, ReflectUtil.getFieldValue(resource, field.getName())); - } + for (Field field : fields) JDKUtils.copyFieldVal(resource, vo, field); +// for (Field field : fields) { +// var rField = ReflectionUtils.findField(resource.getClass(), field.getName()); +// if (Objects.nonNull(rField) && field.trySetAccessible() && rField.trySetAccessible()) +// field.set(vo, rField.get(resource)); + // ReflectUtil.setFieldValue(vo, field, ReflectUtil.getFieldValue(resource, field.getName())); +// } return vo; } } diff --git a/valentine-starter/src/main/resources/config/application.yml b/valentine-starter/src/main/resources/config/application.yml index 798bb07d0..76e7d4bcc 100644 --- a/valentine-starter/src/main/resources/config/application.yml +++ b/valentine-starter/src/main/resources/config/application.yml @@ -32,7 +32,7 @@ spring: open-in-view: true hibernate: ddl-auto: none - # show-sql: true + #show-sql: true autoconfigure: # to use VT, should exclude this exclude: org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration @@ -52,7 +52,7 @@ local: load-os: true # 相同服务的各实例会有不同的配置,从而使得一些事件能被各实例都消费一次,理论上有更好地解决方案 sp-sync-queue: xs.sp-sync.queue - # sim-auth: true + #sim-auth: true extra-ut: user-types: - { name: 'FOUR',type: 4, desc: '猜猜我是谁' } From 5c5f618ffc5a2d648d368ead877aa6bb604d04a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:41:51 +0800 Subject: [PATCH 11/15] Bump gradle/gradle-build-action from 2.3.3 to 2.4.0 (#8) Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2.3.3 to 2.4.0. - [Release notes](https://github.com/gradle/gradle-build-action/releases) - [Commits](https://github.com/gradle/gradle-build-action/compare/3fbe033aaae657f011f88f29be9e65ed26bd29ef...6095a76664413da4c8c134ee32e8a8ae900f0f1f) --- updated-dependencies: - dependency-name: gradle/gradle-build-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- .github/workflows/gradle-publish.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index f604137e2..9d29ac382 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -30,7 +30,7 @@ jobs: settings-path: ${{ github.workspace }} # location for the settings.xml file - name: Build with Gradle - uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef + uses: gradle/gradle-build-action@6095a76664413da4c8c134ee32e8a8ae900f0f1f env: OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 80bc450b9..4cfb8ec57 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,14 +30,14 @@ jobs: settings-path: ${{ github.workspace }} # location for the settings.xml file - name: Build with Gradle - uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef + uses: gradle/gradle-build-action@6095a76664413da4c8c134ee32e8a8ae900f0f1f with: arguments: build # The USERNAME and TOKEN need to correspond to the credentials environment variables used in # the publishing section of your build.gradle - name: Publish to GitHub Packages - uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef + uses: gradle/gradle-build-action@6095a76664413da4c8c134ee32e8a8ae900f0f1f with: arguments: publish env: From a082d8e1fa4750b1a4168e38c28f6631f1bbc6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Wed, 22 Feb 2023 20:50:37 +0800 Subject: [PATCH 12/15] Clarify the reason of pre-commit --- .../java/com/lwohvye/core/utils/JDKUtils.java | 2 +- .../com/lwohvye/core/utils/TestVarargs.java | 96 +++++++++++++++++++ .../RabbitMQAuthMsgConsumerService.java | 19 +++- .../RabbitMQDelayMsgConsumerService.java | 3 - 4 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 unicorn-core/src/test/java/com/lwohvye/core/utils/TestVarargs.java diff --git a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java index 982ee066f..f883fb6d5 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java @@ -410,7 +410,7 @@ public static T invokeMethod(Object obj, String methodName, Class rType) * MethodType的pTypes需要与目标方法签名一致(不支持向上/向下转型,比如用Integer去获取入参为Number的方法是不允许的,同样用Number去获取入参为Integer的方法也不行。这个还能理解), * rtype需要与目标方法的返回值一致(不允许向上/向下转型。不允许向下很容易理解,为何要不允许向上转型,有点不理解)。以上并不是下面问题的原因 * 该方法的使用场景很有限,因为虽然invoke的入参是可变参数,但本方法入参中的可变参数会被转成数组,把数组传给invoke与本方法的原入参是不一样的 (原来会是包含各种类型的可变参数,转换后变成单纯的Object[]),也就导致了与直接调用存在差异 - * 这种感觉主要是底层的解析逻辑,当考虑做为中间层传递这种可变参数时,⚠️可能会出现问题 + * 这里出问题,感觉是因为处理时,底层把Object[]看成一个独立的参数了,而非当可变参数处理,可以这样理解,转成数组是结果,直接传数组时,普通方法间能应对,但MethodHandle不行,这又牵涉到其底层机制了,有时间可以再看看 * * @param obj callInstance * @param methodName invokeMethodName diff --git a/unicorn-core/src/test/java/com/lwohvye/core/utils/TestVarargs.java b/unicorn-core/src/test/java/com/lwohvye/core/utils/TestVarargs.java new file mode 100644 index 000000000..b8362df91 --- /dev/null +++ b/unicorn-core/src/test/java/com/lwohvye/core/utils/TestVarargs.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023. lWoHvYe(Hongyan Wang) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.lwohvye.core.utils; + +import org.junit.jupiter.api.Test; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class TestVarargs { + + + @Test + void test1() throws Throwable { + var varArgs = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, String.class, Boolean.class)); + varArgs.invoke(this, "str", true); // pass + System.out.println("---------"); + var varArgs2 = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, new Class[]{String.class, Boolean.class})); + varArgs2.invoke(this, "str", true); // pass + } + + @Test + void test2() throws Throwable { + // java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(TestVarargs,String,Boolean)void to (TestVarargs,Object[])void + var varArgs = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, String.class, Boolean.class)); + varArgs.invoke(this, new Object[]{"str", true}); // failed + System.out.println("---------"); + var varArgs2 = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, new Class[]{String.class, Boolean.class})); + varArgs2.invoke(this, new Object[]{"str", true}); // failed + } + + void varArgs(String s, Boolean b) { + System.out.println(s + " | " + b); + } + + + @Test + void test4() throws Throwable { + varArgs2("str", false); + } + + void varArgs2(Object... args) throws Throwable { + // java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(TestVarargs,String,Boolean)void to (TestVarargs,Object[])void + var varArgs = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, String.class, Boolean.class)); + varArgs.invoke(this, args); // failed + System.out.println("---------"); + var varArgs2 = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs", MethodType.methodType(void.class, new Class[]{String.class, Boolean.class})); + varArgs2.invoke(this, args); // failed + } + + @Test + void test3() throws Throwable { + varArgs4("str"); + } + + void varArgs4(Object... args) throws Throwable { + // java.lang.ClassCastException: Cannot cast [Ljava.lang.Object; to java.lang.String 这里注意是Object[],一个参数时稍不注意就被掩盖了重要的问题 + var varArgs = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs1", MethodType.methodType(void.class, String.class)); + varArgs.invoke(this, args); // failed + System.out.println("---------"); + var varArgs2 = MethodHandles.lookup().findVirtual(TestVarargs.class, "varArgs1", MethodType.methodType(void.class, new Class[]{String.class})); + varArgs2.invoke(this, args); // failed + } + + void varArgs1(String str) { + System.out.println(str); + } + + @Test + void test5() { // pass + varArgs3("a", "b"); + } + + void varArgs3(String... args) { + varArgs6(args); + System.out.println(args); + } + + void varArgs6(String... args) { + System.out.println(args); + } +} diff --git a/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitMQAuthMsgConsumerService.java b/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitMQAuthMsgConsumerService.java index 80bdaa5a9..d469b769a 100644 --- a/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitMQAuthMsgConsumerService.java +++ b/unicorn-logging/src/main/java/com/lwohvye/log/rabbitmq/RabbitMQAuthMsgConsumerService.java @@ -15,11 +15,11 @@ */ package com.lwohvye.log.rabbitmq; -import cn.hutool.core.util.ReflectUtil; -import com.lwohvye.log.service.local.MultiLogService; +import com.lwohvye.core.exception.UtilsException; import com.lwohvye.core.utils.MailAdapter; import com.lwohvye.core.utils.rabbitmq.AmqpMsgEntity; import com.lwohvye.core.utils.rabbitmq.YRabbitAbstractConsumer; +import com.lwohvye.log.service.local.MultiLogService; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RedissonClient; import org.springframework.amqp.rabbit.annotation.RabbitHandler; @@ -28,6 +28,8 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.Map; @Component @@ -39,6 +41,8 @@ public class RabbitMQAuthMsgConsumerService extends YRabbitAbstractConsumer { @Autowired private MultiLogService multiLogService; + private final MethodHandles.Lookup lookup = MethodHandles.lookup(); + @Autowired public void setRedissonClient(RedissonClient redissonClient) { super.redissonClient = redissonClient; @@ -49,8 +53,15 @@ public void setRedissonClient(RedissonClient redissonClient) { public void handle(String amqpMsgEntityStr) { baseConsumer(amqpMsgEntityStr, "authSave", null, msgEntity -> { var extraData = msgEntity.getExtraData(); - if (StringUtils.hasText(extraData)) - ReflectUtil.invoke(multiLogService, extraData, msgEntity.getMsgData()); + if (StringUtils.hasText(extraData)) { + try { + var mt = MethodType.methodType(void.class, String.class); + var methodHandle = lookup.findVirtual(multiLogService.getClass(), extraData, mt); + methodHandle.invoke(multiLogService, msgEntity.getMsgData()); + } catch (Throwable e) { + throw new UtilsException(e.getMessage()); + } + } return null; }, errMsg -> { // reConsumeMsg(this::handle, amqpMsgEntityStr); diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java index b89ac3379..d403d41b2 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/rabbitmq/service/RabbitMQDelayMsgConsumerService.java @@ -73,9 +73,6 @@ public void handle(String amqpMsgEntityStr) { var mt = MethodType.methodType(void.class, new Class[]{String.class}); var methodHandle = lookup.findVirtual(authMQService.getClass(), extraData, mt); methodHandle.invoke(authMQService, msgEntity.getMsgData()); -// methodHandle.invoke(authMQService, new Object[]{msgEntity.getMsgData()}); // Cannot cast [Ljava.lang.Object; to java.lang.String -// methodHandle.invoke(new Object[]{authMQService, msgEntity.getMsgData()}); // cannot convert MethodHandle(AuthMQService,String)void to (Object[])void - // 至此,便明白了,虽然方法入参是可变参数,但传多个参数跟传一个数组近去处理方面是不一样的,暂不清楚原因 } catch (Throwable e) { throw new UtilsException(e.getMessage()); } From afc2c248feee8bdc96b3e426dd4965d5c16413f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Thu, 23 Feb 2023 19:50:11 +0800 Subject: [PATCH 13/15] try LambdaMetafactory --- .../java/com/lwohvye/core/utils/JDKUtils.java | 2 +- .../sys/modules/system/event/BaseEvent.java | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java index f883fb6d5..1e2284dd2 100644 --- a/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java +++ b/unicorn-core/src/main/java/com/lwohvye/core/utils/JDKUtils.java @@ -331,7 +331,7 @@ public static char[] getCharArray(String str) { /** * JDK 8开始支持Lambda,为了方便将一个Method映射为一个Lambda Function,避免反射开销。 - * java.invoke.LambdaMetaFactory 可以实现这一功能,但这个也受限于可见性的限制,也就是说不能调用私有方法。 + * java.invoke.LambdaMetafactory 可以实现这一功能,但这个也受限于可见性的限制,也就是说不能调用私有方法。 * 有一个技巧,结合Unsafe,可以在不同版本的JDK都能构造一个Trusted MethodHandles.Lookup来绕开可见性的限制,调用任何JDK内部方法。 * * @param objectClass diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java index 419dde978..a21ec8011 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java @@ -16,11 +16,14 @@ package com.lwohvye.sys.modules.system.event; +import com.lwohvye.core.utils.JDKUtils; import lombok.Getter; import lombok.SneakyThrows; import org.springframework.context.ApplicationEvent; -import java.lang.invoke.MethodHandles; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodType; +import java.util.function.ToLongFunction; /** * Doc Page @@ -54,6 +57,20 @@ public Long getDataId() { var aClass = eventData.getClass(); // 有定义public的getter的话,可以用这个 // return (Long) MethodHandles.lookup().findVirtual(aClass, "getId", MethodType.methodType(Long.class)).invoke(eventData); // 1.7的方式 - return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 + // return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 + // 使用LambdaMetafactory,这个比上面的复杂多了。算是lambda函数映射的一个使用 + /*ToLongFunction function = T::getId; + var id = function.applyAsLong(eventData);*/ + // 这个跟👆这个是等价的,但此次上面这个是无法编译的,👇这个就没问题,这很容易理解 + var lookup = JDKUtils.trustedLookup(aClass); + var callSite = LambdaMetafactory.metafactory( + lookup, + "applyAsLong", + MethodType.methodType(ToLongFunction.class), + MethodType.methodType(long.class, Object.class), // 这里必须是long,Long是不行的 + lookup.findVirtual(aClass, "getId", MethodType.methodType(Long.class)), // 这里必须是Long,long是不行的 + MethodType.methodType(long.class, aClass)); // 这里long和Long都可以 + var function = (ToLongFunction) callSite.getTarget().invokeExact(); + return function.applyAsLong(eventData); } } From d1e6bf31b68a424f11d57b4e381576f7f42aa2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Fri, 24 Feb 2023 08:29:43 +0800 Subject: [PATCH 14/15] =?UTF-8?q?=E5=A6=82=E6=9E=9C=E8=83=BD=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=A4=8D=E7=94=A8=EF=BC=8C=E5=88=99LambdaMetafactory?= =?UTF-8?q?=E4=BC=9A=E6=9C=89=E6=AF=94=E8=BE=83=E5=A4=A7=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8A=BF=EF=BC=8C=E4=B8=8D=E7=84=B6=E6=98=AF=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E4=B8=8D=E5=8F=8AfindVirtual=E7=9A=84=EF=BC=8C=E5=85=B7?= =?UTF-8?q?=E4=BD=93=E7=9C=8B=E9=9A=8F=E9=99=84=E7=9A=84UT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sys/modules/system/event/BaseEvent.java | 13 +-- .../src/test/java/MultiFunction.java | 22 +++++ unicorn-security/src/test/java/Tst.java | 92 +++++++++++++++++++ 3 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 unicorn-security/src/test/java/MultiFunction.java create mode 100644 unicorn-security/src/test/java/Tst.java diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java index a21ec8011..a6291f57a 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java @@ -16,14 +16,11 @@ package com.lwohvye.sys.modules.system.event; -import com.lwohvye.core.utils.JDKUtils; import lombok.Getter; import lombok.SneakyThrows; import org.springframework.context.ApplicationEvent; -import java.lang.invoke.LambdaMetafactory; -import java.lang.invoke.MethodType; -import java.util.function.ToLongFunction; +import java.lang.invoke.MethodHandles; /** * Doc Page @@ -57,12 +54,12 @@ public Long getDataId() { var aClass = eventData.getClass(); // 有定义public的getter的话,可以用这个 // return (Long) MethodHandles.lookup().findVirtual(aClass, "getId", MethodType.methodType(Long.class)).invoke(eventData); // 1.7的方式 - // return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 - // 使用LambdaMetafactory,这个比上面的复杂多了。算是lambda函数映射的一个使用 + return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 + // 使用LambdaMetafactory,这个比上面的复杂多了。算是lambda函数映射的一个使用,这个需要函数复用才能有优势,不然会比findVirtual慢很多 /*ToLongFunction function = T::getId; var id = function.applyAsLong(eventData);*/ // 这个跟👆这个是等价的,但此次上面这个是无法编译的,👇这个就没问题,这很容易理解 - var lookup = JDKUtils.trustedLookup(aClass); + /*var lookup = JDKUtils.trustedLookup(aClass); var callSite = LambdaMetafactory.metafactory( lookup, "applyAsLong", @@ -71,6 +68,6 @@ public Long getDataId() { lookup.findVirtual(aClass, "getId", MethodType.methodType(Long.class)), // 这里必须是Long,long是不行的 MethodType.methodType(long.class, aClass)); // 这里long和Long都可以 var function = (ToLongFunction) callSite.getTarget().invokeExact(); - return function.applyAsLong(eventData); + return function.applyAsLong(eventData);*/ } } diff --git a/unicorn-security/src/test/java/MultiFunction.java b/unicorn-security/src/test/java/MultiFunction.java new file mode 100644 index 000000000..889f730c3 --- /dev/null +++ b/unicorn-security/src/test/java/MultiFunction.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023. lWoHvYe(Hongyan Wang) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.function.Function; + +@FunctionalInterface +public interface MultiFunction { + Integer runFun(Function function, String str); +} diff --git a/unicorn-security/src/test/java/Tst.java b/unicorn-security/src/test/java/Tst.java new file mode 100644 index 000000000..afaca3250 --- /dev/null +++ b/unicorn-security/src/test/java/Tst.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023. lWoHvYe(Hongyan Wang) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.junit.jupiter.api.Test; + +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.ArrayList; +import java.util.function.Function; + +class Tst { + + @Test + void testLambdaParams() throws Throwable { + + MultiFunction fun = Function::apply; + var i = fun.runFun(Integer::valueOf, "2"); + + var lookup = MethodHandles.lookup(); + var runFun = lookup.findVirtual(MultiFunction.class, "runFun", MethodType.methodType(Integer.class, Function.class, String.class)); +// runFun.invoke(fun, Integer::valueOf, "3"); // 编译error: Object is not a functional interface + Function innerFun = Integer::valueOf; // 虽然直接不行,但可以封装成Function,然后就可以了 + var i2 = runFun.invoke(fun, innerFun, "3"); // 所以findVirtual也可以应对参数包含lambda的method + + var multiFunction = (MultiFunction) LambdaMetafactory.metafactory( + lookup, + "runFun", // interfaceMethodName + MethodType.methodType(MultiFunction.class), // factoryType + MethodType.methodType(Integer.class, Function.class, String.class), // interfaceMethodType + lookup.findVirtual(Function.class, "apply", MethodType.methodType(Object.class, Object.class)), // implementation + MethodType.methodType(Integer.class, Function.class, String.class) // dynamicMethodType + ).getTarget().invokeExact(); + var i4 = multiFunction.runFun(Integer::valueOf, "4"); + + } + + + @Test + void test1() throws Throwable { // 复用前291ms,函数复用后38ms + MultiFunction fun = Function::apply; + var lookup = MethodHandles.lookup(); + var runFun = lookup.findVirtual(MultiFunction.class, "runFun", MethodType.methodType(Integer.class, Function.class, String.class)); +// runFun.invoke(fun, Integer::valueOf, "3"); // 编译error: Object is not a functional interface + Function innerFun = Integer::valueOf; // 虽然直接不行,但可以封装成Function,然后就可以了 + var list = new ArrayList(100000); + for (int i = 0; i < 100000; i++) { + list.add(m1(runFun, fun, innerFun, "3")); + } + System.out.println(list.size()); + } + + Integer m1(MethodHandle runFun, MultiFunction fun, Function innerFun, String str) throws Throwable { + return (Integer) runFun.invoke(fun, innerFun, str); // 所以findVirtual也可以应对参数包含lambda的method + } + + @Test + void test2() throws Throwable { // 复用前4s191ms,函数复用后28ms + var lookup = MethodHandles.lookup(); + var multiFunction = (MultiFunction) LambdaMetafactory.metafactory( + lookup, + "runFun", // interfaceMethodName + MethodType.methodType(MultiFunction.class), // factoryType + MethodType.methodType(Integer.class, Function.class, String.class), // interfaceMethodType + lookup.findVirtual(Function.class, "apply", MethodType.methodType(Object.class, Object.class)), // implementation + MethodType.methodType(Integer.class, Function.class, String.class) // dynamicMethodType + ).getTarget().invokeExact(); // 这部分复用,就会快很多 + var list = new ArrayList(100000); + for (int i = 0; i < 100000; i++) { + list.add(m2(multiFunction, "4")); + } + System.out.println(list.size()); + } + + Integer m2(MultiFunction multiFunction, String str) { + return multiFunction.runFun(Integer::valueOf, str); + } +} From e97633ebf5761ad215885f0af3c605cd3742e59e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BA=A2=E5=B2=A9=20lWoHvYe?= Date: Fri, 24 Feb 2023 08:44:21 +0800 Subject: [PATCH 15/15] format name --- .../sys/modules/system/event/BaseEvent.java | 2 +- .../test/java/{Tst.java => LambdaMetaTest.java} | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) rename unicorn-security/src/test/java/{Tst.java => LambdaMetaTest.java} (89%) diff --git a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java index a6291f57a..8d3cf9e13 100644 --- a/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java +++ b/unicorn-security/src/main/java/com/lwohvye/sys/modules/system/event/BaseEvent.java @@ -54,7 +54,7 @@ public Long getDataId() { var aClass = eventData.getClass(); // 有定义public的getter的话,可以用这个 // return (Long) MethodHandles.lookup().findVirtual(aClass, "getId", MethodType.methodType(Long.class)).invoke(eventData); // 1.7的方式 - return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 + return (Long) MethodHandles.privateLookupIn(aClass, MethodHandles.lookup()).findVarHandle(aClass, "id", Long.class).get(eventData); // 1.9的方式 // 使用LambdaMetafactory,这个比上面的复杂多了。算是lambda函数映射的一个使用,这个需要函数复用才能有优势,不然会比findVirtual慢很多 /*ToLongFunction function = T::getId; var id = function.applyAsLong(eventData);*/ diff --git a/unicorn-security/src/test/java/Tst.java b/unicorn-security/src/test/java/LambdaMetaTest.java similarity index 89% rename from unicorn-security/src/test/java/Tst.java rename to unicorn-security/src/test/java/LambdaMetaTest.java index afaca3250..8562083a5 100644 --- a/unicorn-security/src/test/java/Tst.java +++ b/unicorn-security/src/test/java/LambdaMetaTest.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.util.function.Function; -class Tst { +class LambdaMetaTest { @Test void testLambdaParams() throws Throwable { @@ -51,7 +51,7 @@ void testLambdaParams() throws Throwable { @Test - void test1() throws Throwable { // 复用前291ms,函数复用后38ms + void testInvoke() throws Throwable { // 复用前291ms,函数复用后38ms MultiFunction fun = Function::apply; var lookup = MethodHandles.lookup(); var runFun = lookup.findVirtual(MultiFunction.class, "runFun", MethodType.methodType(Integer.class, Function.class, String.class)); @@ -59,17 +59,17 @@ void test1() throws Throwable { // 复用前291ms,函数复用后38ms Function innerFun = Integer::valueOf; // 虽然直接不行,但可以封装成Function,然后就可以了 var list = new ArrayList(100000); for (int i = 0; i < 100000; i++) { - list.add(m1(runFun, fun, innerFun, "3")); + list.add(handleInvoke(runFun, fun, innerFun, "3")); } System.out.println(list.size()); } - Integer m1(MethodHandle runFun, MultiFunction fun, Function innerFun, String str) throws Throwable { + Integer handleInvoke(MethodHandle runFun, MultiFunction fun, Function innerFun, String str) throws Throwable { return (Integer) runFun.invoke(fun, innerFun, str); // 所以findVirtual也可以应对参数包含lambda的method } @Test - void test2() throws Throwable { // 复用前4s191ms,函数复用后28ms + void testLambda() throws Throwable { // 复用前4s191ms,函数复用后28ms var lookup = MethodHandles.lookup(); var multiFunction = (MultiFunction) LambdaMetafactory.metafactory( lookup, @@ -81,12 +81,12 @@ void test2() throws Throwable { // 复用前4s191ms,函数复用后28ms ).getTarget().invokeExact(); // 这部分复用,就会快很多 var list = new ArrayList(100000); for (int i = 0; i < 100000; i++) { - list.add(m2(multiFunction, "4")); + list.add(lambdaMeta(multiFunction, "4")); } System.out.println(list.size()); } - Integer m2(MultiFunction multiFunction, String str) { + Integer lambdaMeta(MultiFunction multiFunction, String str) { return multiFunction.runFun(Integer::valueOf, str); } }