From d78f2df9a870680bc60b90434bb670d7e7a64d2e Mon Sep 17 00:00:00 2001 From: redkale Date: Wed, 25 Oct 2023 08:13:49 +0800 Subject: [PATCH] =?UTF-8?q?HttpSimpleRequest=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/mq/HttpMessageRequest.java | 1 - .../redkale/mq/HttpSimpleRequestCoder.java | 3 - .../java/org/redkale/mq/MessageRecord.java | 13 ---- .../org/redkale/mq/SncpMessageRequest.java | 1 - src/main/java/org/redkale/net/Request.java | 13 ---- .../org/redkale/net/http/HttpRequest.java | 8 +-- .../redkale/net/http/HttpSimpleClient.java | 20 +++++- .../org/redkale/net/http/HttpSimpleCodec.java | 25 +++++++ .../net/http/HttpSimpleConnection.java | 31 ++++++++ .../redkale/net/http/HttpSimpleRequest.java | 72 ++++++++++++------- .../redkale/net/http/HttpSimpleResult.java | 25 +++++++ src/main/java/org/redkale/util/Utility.java | 28 ++++++++ 12 files changed, 176 insertions(+), 64 deletions(-) create mode 100644 src/main/java/org/redkale/net/http/HttpSimpleCodec.java create mode 100644 src/main/java/org/redkale/net/http/HttpSimpleConnection.java create mode 100644 src/main/java/org/redkale/net/http/HttpSimpleResult.java diff --git a/src/main/java/org/redkale/mq/HttpMessageRequest.java b/src/main/java/org/redkale/mq/HttpMessageRequest.java index f1a982022..cc05d9bf0 100644 --- a/src/main/java/org/redkale/mq/HttpMessageRequest.java +++ b/src/main/java/org/redkale/mq/HttpMessageRequest.java @@ -35,7 +35,6 @@ public class HttpMessageRequest extends HttpRequest { protected HttpMessageRequest prepare(MessageRecord message) { super.initSimpleRequest(message.decodeContent(HttpSimpleRequestCoder.getInstance()), false); this.message = message; - this.hashid = this.message.hash(); this.currentUserid = message.getUserid(); this.createTime = System.currentTimeMillis(); return this; diff --git a/src/main/java/org/redkale/mq/HttpSimpleRequestCoder.java b/src/main/java/org/redkale/mq/HttpSimpleRequestCoder.java index e297bcd25..7e19f5edf 100644 --- a/src/main/java/org/redkale/mq/HttpSimpleRequestCoder.java +++ b/src/main/java/org/redkale/mq/HttpSimpleRequestCoder.java @@ -47,7 +47,6 @@ public class HttpSimpleRequestCoder implements MessageCoder { byte[] body = MessageCoder.getBytes(data.getBody()); byte[] userid = MessageCoder.encodeUserid(data.getCurrentUserid()); int count = 1 //rpc + frombody - + 4 //hashid + 4 //reqConvertType + 4 //respConvertType + 2 + traceid.length @@ -62,7 +61,6 @@ public class HttpSimpleRequestCoder implements MessageCoder { byte[] bs = new byte[count]; ByteBuffer buffer = ByteBuffer.wrap(bs); buffer.put((byte) ((data.isRpc() ? 0b01 : 0) | (data.isFrombody() ? 0b10 : 0))); - buffer.putInt(data.getHashid()); buffer.putInt(data.getReqConvertType() == null ? 0 : data.getReqConvertType().getValue()); buffer.putInt(data.getRespConvertType() == null ? 0 : data.getRespConvertType().getValue()); buffer.putChar((char) traceid.length); @@ -112,7 +110,6 @@ public class HttpSimpleRequestCoder implements MessageCoder { byte opt = buffer.get(); req.setRpc((opt & 0b01) > 0); req.setFrombody((opt & 0b10) > 0); - req.setHashid(buffer.getInt()); int reqformat = buffer.getInt(); int respformat = buffer.getInt(); if (reqformat != 0) { diff --git a/src/main/java/org/redkale/mq/MessageRecord.java b/src/main/java/org/redkale/mq/MessageRecord.java index 2121abe26..977379159 100644 --- a/src/main/java/org/redkale/mq/MessageRecord.java +++ b/src/main/java/org/redkale/mq/MessageRecord.java @@ -171,16 +171,6 @@ public class MessageRecord implements Serializable { return this; } - public int hash() { - if (groupid != null && !groupid.isEmpty()) { - return Math.abs(groupid.hashCode()); - } else if (userid != null) { - return Math.abs(userid.hashCode()); - } else { - return 0; - } - } - public MessageRecord version(int version) { this.version = version; return this; @@ -349,9 +339,6 @@ public class MessageRecord implements Serializable { if (req.getCurrentUserid() == null) { req.setCurrentUserid(this.userid); } - if (req.getHashid() == 0) { - req.setHashid(this.hash()); - } } sb.append(",\"content\":").append(req); } else if (this.ctype == CTYPE_HTTP_RESULT) { diff --git a/src/main/java/org/redkale/mq/SncpMessageRequest.java b/src/main/java/org/redkale/mq/SncpMessageRequest.java index 374ce42ec..cec23b478 100644 --- a/src/main/java/org/redkale/mq/SncpMessageRequest.java +++ b/src/main/java/org/redkale/mq/SncpMessageRequest.java @@ -25,7 +25,6 @@ public class SncpMessageRequest extends SncpRequest { public SncpMessageRequest(SncpContext context, MessageRecord message) { super(context); this.message = message; - this.hashid = this.message.hash(); this.createTime = System.currentTimeMillis(); readHeader(ByteBuffer.wrap(message.getContent()), null); } diff --git a/src/main/java/org/redkale/net/Request.java b/src/main/java/org/redkale/net/Request.java index 363a13ac9..b5b9fe0a8 100644 --- a/src/main/java/org/redkale/net/Request.java +++ b/src/main/java/org/redkale/net/Request.java @@ -39,8 +39,6 @@ public abstract class Request { protected boolean pipelineCompleted; - protected int hashid; - protected String traceid; protected AsyncConnection channel; @@ -68,7 +66,6 @@ public abstract class Request { this.pipelineIndex = request.pipelineIndex; this.pipelineCount = request.pipelineCount; this.pipelineCompleted = request.pipelineCompleted; - this.hashid = request.hashid; this.traceid = request.traceid; this.channel = request.channel; } @@ -98,7 +95,6 @@ public abstract class Request { protected abstract void prepare(); protected void recycle() { - hashid = 0; traceid = null; createTime = 0; pipelineIndex = 0; @@ -169,15 +165,6 @@ public abstract class Request { return createTime; } - public int getHashid() { - return hashid; - } - - public Request hashid(int hashid) { - this.hashid = hashid; - return this; - } - public String getTraceid() { return traceid; } diff --git a/src/main/java/org/redkale/net/http/HttpRequest.java b/src/main/java/org/redkale/net/http/HttpRequest.java index 5f2139962..22e3cd0e9 100644 --- a/src/main/java/org/redkale/net/http/HttpRequest.java +++ b/src/main/java/org/redkale/net/http/HttpRequest.java @@ -220,7 +220,6 @@ public class HttpRequest extends Request { if (req.getParams() != null) { this.params.putAll(req.getParams()); } - this.hashid = req.getHashid(); if (req.getCurrentUserid() != null) { this.currentUserid = req.getCurrentUserid(); } @@ -232,7 +231,7 @@ public class HttpRequest extends Request { } else { this.requestURI = req.getRequestURI(); } - this.method = METHOD_POST; + this.method = req.getMethod(); if (req.getSessionid() != null && !req.getSessionid().isEmpty()) { this.cookies = new HttpCookie[]{new HttpCookie(SESSIONID_NAME, req.getSessionid())}; } @@ -258,11 +257,11 @@ public class HttpRequest extends Request { req.setLocale(getLocale()); req.setContentType(getContentType()); req.setPath(prefix); + req.setMethod(this.method); String uri = this.requestURI; if (prefix != null && !prefix.isEmpty() && uri.startsWith(prefix)) { uri = uri.substring(prefix.length()); } - req.setHashid(this.hashid); req.setRequestURI(uri); req.setSessionid(getSessionid(false)); req.setRpc(this.rpc); @@ -323,7 +322,6 @@ public class HttpRequest extends Request { this.expect = httplast.expect; this.rpc = httplast.rpc; this.traceid = httplast.traceid; - this.hashid = httplast.hashid; this.currentUserid = httplast.currentUserid; this.frombody = httplast.frombody; this.reqConvertType = httplast.reqConvertType; @@ -822,7 +820,6 @@ public class HttpRequest extends Request { break; case Rest.REST_HEADER_CURRUSERID: //rest-curruserid value = bytes.toString(true, charset); - this.hashid = value.hashCode(); this.currentUserid = value; headers.put(name, value); break; @@ -949,7 +946,6 @@ public class HttpRequest extends Request { req.expect = this.expect; req.rpc = this.rpc; req.traceid = this.traceid; - req.hashid = this.hashid; req.currentUserid = this.currentUserid; req.currentUserSupplier = this.currentUserSupplier; req.frombody = this.frombody; diff --git a/src/main/java/org/redkale/net/http/HttpSimpleClient.java b/src/main/java/org/redkale/net/http/HttpSimpleClient.java index 0411c3578..3af00610a 100644 --- a/src/main/java/org/redkale/net/http/HttpSimpleClient.java +++ b/src/main/java/org/redkale/net/http/HttpSimpleClient.java @@ -15,6 +15,9 @@ import java.util.concurrent.*; import org.redkale.convert.Convert; import org.redkale.convert.json.JsonConvert; import org.redkale.net.*; +import org.redkale.net.client.Client; +import org.redkale.net.client.ClientAddress; +import org.redkale.net.client.ClientConnection; import static org.redkale.net.http.HttpRequest.parseHeaderName; import org.redkale.util.*; @@ -32,13 +35,13 @@ import org.redkale.util.*; * @since 2.3.0 * */ -public class HttpSimpleClient { +public class HttpSimpleClient extends Client { public static final String USER_AGENT = "Redkale-http-client/" + Redkale.getDotedVersion(); - private static final byte[] header_bytes_useragent = ("User-Agent: " + USER_AGENT + "\r\n").getBytes(StandardCharsets.UTF_8); + static final byte[] header_bytes_useragent = ("User-Agent: " + USER_AGENT + "\r\n").getBytes(StandardCharsets.UTF_8); - private static final byte[] header_bytes_connclose = ("Connection: close\r\n").getBytes(StandardCharsets.UTF_8); + static final byte[] header_bytes_connclose = ("Connection: close\r\n").getBytes(StandardCharsets.UTF_8); protected final AsyncGroup asyncGroup; @@ -49,6 +52,7 @@ public class HttpSimpleClient { protected int writeTimeoutSeconds = 6; protected HttpSimpleClient(ExecutorService workExecutor, AsyncGroup asyncGroup) { + super("Redkale-http-client", asyncGroup, new ClientAddress(new InetSocketAddress("127.0.0.1", 0))); this.workExecutor = workExecutor; this.asyncGroup = asyncGroup; } @@ -61,6 +65,16 @@ public class HttpSimpleClient { return create(null, asyncGroup); } + @Override + protected HttpSimpleConnection createClientConnection(int index, AsyncConnection channel) { + return new HttpSimpleConnection(this, index, channel); + } + + @Override + protected CompletableFuture writeChannel(ClientConnection conn, HttpSimpleRequest request) { + return super.writeChannel(conn, request); + } + public HttpSimpleClient readTimeoutSeconds(int readTimeoutSeconds) { this.readTimeoutSeconds = readTimeoutSeconds; return this; diff --git a/src/main/java/org/redkale/net/http/HttpSimpleCodec.java b/src/main/java/org/redkale/net/http/HttpSimpleCodec.java new file mode 100644 index 000000000..a5948f6b9 --- /dev/null +++ b/src/main/java/org/redkale/net/http/HttpSimpleCodec.java @@ -0,0 +1,25 @@ +/* + * + */ +package org.redkale.net.http; + +import java.nio.ByteBuffer; +import org.redkale.net.client.ClientCodec; +import org.redkale.util.ByteArray; + +/** + * + * @author zhangjx + */ +class HttpSimpleCodec extends ClientCodec { + + public HttpSimpleCodec(HttpSimpleConnection connection) { + super(connection); + } + + @Override + public void decodeMessages(ByteBuffer buffer, ByteArray array) { + + } + +} diff --git a/src/main/java/org/redkale/net/http/HttpSimpleConnection.java b/src/main/java/org/redkale/net/http/HttpSimpleConnection.java new file mode 100644 index 000000000..4ba713eb9 --- /dev/null +++ b/src/main/java/org/redkale/net/http/HttpSimpleConnection.java @@ -0,0 +1,31 @@ +/* + * + */ +package org.redkale.net.http; + +import org.redkale.net.AsyncConnection; +import org.redkale.net.client.ClientCodec; +import org.redkale.net.client.ClientConnection; + +/** + * + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * + * @since 2.8.0 + */ +class HttpSimpleConnection extends ClientConnection { + + public HttpSimpleConnection(HttpSimpleClient client, int index, AsyncConnection channel) { + super(client, index, channel); + } + + @Override + protected ClientCodec createCodec() { + return new HttpSimpleCodec(this); + } + +} diff --git a/src/main/java/org/redkale/net/http/HttpSimpleRequest.java b/src/main/java/org/redkale/net/http/HttpSimpleRequest.java index 01b8c1696..41eb8953d 100644 --- a/src/main/java/org/redkale/net/http/HttpSimpleRequest.java +++ b/src/main/java/org/redkale/net/http/HttpSimpleRequest.java @@ -13,6 +13,9 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.redkale.annotation.Comment; import org.redkale.convert.*; import org.redkale.convert.json.JsonConvert; +import org.redkale.net.client.ClientConnection; +import org.redkale.net.client.ClientRequest; +import org.redkale.util.ByteArray; import org.redkale.util.Traces; /** @@ -25,7 +28,7 @@ import org.redkale.util.Traces; * * @since 2.1.0 */ -public class HttpSimpleRequest implements java.io.Serializable { +public class HttpSimpleRequest extends ClientRequest implements java.io.Serializable { @ConvertColumn(index = 1) @Comment("是否RPC请求, 该类通常是为RPC创建的,故默认是true") @@ -47,33 +50,34 @@ public class HttpSimpleRequest implements java.io.Serializable { @Comment("输出结果的ConvertType") protected ConvertType respConvertType; + @Comment("Method GET/POST/...") @ConvertColumn(index = 6) + protected String method; + + @ConvertColumn(index = 7) @Comment("请求的URI") protected String requestURI; - @ConvertColumn(index = 7) + @ConvertColumn(index = 8) @Comment("请求的前缀") protected String path; - @ConvertColumn(index = 8) + @ConvertColumn(index = 9) @Comment("客户端IP") protected String remoteAddr; - @ConvertColumn(index = 9) + @ConvertColumn(index = 10) @Comment("Locale国际化") protected String locale; - @ConvertColumn(index = 10) + @ConvertColumn(index = 11) @Comment("会话ID") protected String sessionid; - @ConvertColumn(index = 11) + @ConvertColumn(index = 12) @Comment("Content-Type") protected String contentType; - @ConvertColumn(index = 12) - protected int hashid; - @ConvertColumn(index = 13) //@since 2.5.0 由int改成Serializable, 具体数据类型只能是int、long、String protected Serializable currentUserid; @@ -90,11 +94,11 @@ public class HttpSimpleRequest implements java.io.Serializable { protected byte[] body; //对应HttpRequest.array public static HttpSimpleRequest create(String requestURI) { - return new HttpSimpleRequest().requestURI(requestURI).traceid(Traces.currentTraceid()); + return new HttpSimpleRequest().requestURI(requestURI).method("POST").traceid(Traces.currentTraceid()); } public static HttpSimpleRequest create(String requestURI, Object... params) { - HttpSimpleRequest req = new HttpSimpleRequest().requestURI(requestURI).traceid(Traces.currentTraceid()); + HttpSimpleRequest req = new HttpSimpleRequest().requestURI(requestURI).method("POST").traceid(Traces.currentTraceid()); int len = params.length / 2; for (int i = 0; i < len; i++) { req.param(params[i * 2].toString(), params[i * 2 + 1]); @@ -102,6 +106,26 @@ public class HttpSimpleRequest implements java.io.Serializable { return req; } + public static HttpSimpleRequest create(String requestURI, Map headers) { + return new HttpSimpleRequest().requestURI(requestURI).method("POST").headers(headers).traceid(Traces.currentTraceid()); + } + + @Override + public void writeTo(ClientConnection conn, ByteArray array) { + array.put((method.toUpperCase() + " " + requestURI + " HTTP/1.1\r\n" + + Rest.REST_HEADER_TRACEID + ": " + traceid + "\r\n" + + "Content-Length: " + (body == null ? 0 : body.length) + "\r\n").getBytes(StandardCharsets.UTF_8)); + if (headers != null) { + headers.forEach((k, v) -> { + array.put((k + ": " + v + "\r\n").getBytes(StandardCharsets.UTF_8)); + }); + } + array.put((byte) '\r', (byte) '\n'); + if (body != null) { + array.put(body); + } + } + @ConvertDisabled public String getParametersToString() { if (this.params == null || this.params.isEmpty()) { @@ -185,11 +209,6 @@ public class HttpSimpleRequest implements java.io.Serializable { return this; } - public HttpSimpleRequest hashid(int hashid) { - this.hashid = hashid; - return this; - } - public HttpSimpleRequest currentUserid(Serializable userid) { this.currentUserid = userid; return this; @@ -219,6 +238,11 @@ public class HttpSimpleRequest implements java.io.Serializable { return this; } + public HttpSimpleRequest method(String method) { + this.method = method; + return this; + } + public HttpSimpleRequest header(String key, String value) { if (this.headers == null) { this.headers = new HashMap<>(); @@ -352,6 +376,14 @@ public class HttpSimpleRequest implements java.io.Serializable { this.traceid = traceid; } + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + public String getRequestURI() { return requestURI; } @@ -392,14 +424,6 @@ public class HttpSimpleRequest implements java.io.Serializable { this.locale = locale; } - public int getHashid() { - return hashid; - } - - public void setHashid(int hashid) { - this.hashid = hashid; - } - public Serializable getCurrentUserid() { return currentUserid; } diff --git a/src/main/java/org/redkale/net/http/HttpSimpleResult.java b/src/main/java/org/redkale/net/http/HttpSimpleResult.java new file mode 100644 index 000000000..00e05484f --- /dev/null +++ b/src/main/java/org/redkale/net/http/HttpSimpleResult.java @@ -0,0 +1,25 @@ +/* + * + */ +package org.redkale.net.http; + +import org.redkale.net.client.ClientResult; + +/** + * + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * + * @since 2.8.0 + */ +class HttpSimpleResult extends HttpResult implements ClientResult { + + @Override + public boolean isKeepAlive() { + return true; + } + +} diff --git a/src/main/java/org/redkale/util/Utility.java b/src/main/java/org/redkale/util/Utility.java index a560381f9..a09e056c7 100644 --- a/src/main/java/org/redkale/util/Utility.java +++ b/src/main/java/org/redkale/util/Utility.java @@ -71,6 +71,13 @@ public final class Utility { JAVA_RECORD_CLASS = clz; } + private static final Executor defaultExecutorConsumer = new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; + //org.redkale.util.AnonymousThreadLocal private static final String functionThreadLocalBinary = "cafebabe0000004100480a000200030700040c000500060100156a6176612f6c616e672f5468726561644c6f63616c0100063c696e69743e010003282956090008000907000a0c000b000c0100256f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c010008737570706c69657201001d4c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b0a0008000e0c0005000f010020284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b29560b001100120700130c0014001501001b6a6176612f7574696c2f66756e6374696f6e2f537570706c69657201000367657401001428294c6a6176612f6c616e672f4f626a6563743b0a001700180700190c001a001b0100106a6176612f6c616e672f54687265616401000d63757272656e7454687265616401001428294c6a6176612f6c616e672f5468726561643b0a0017001d0c001e001f01000969735669727475616c01000328295a0a000200210c00220023010003736574010015284c6a6176612f6c616e672f4f626a6563743b29560a000800250c0026001501000c696e697469616c56616c75650a000200120a000800290c002a002b0100056170706c79010036284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b294c6a6176612f6c616e672f5468726561644c6f63616c3b07002d01001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e0100095369676e61747572650100224c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100274c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c3b0100164c6f63616c5661726961626c65547970655461626c6501002c4c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c3c54543b3e3b0100104d6574686f64506172616d6574657273010025284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b2956010040284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b294c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b010005282954543b01000576616c75650100124c6a6176612f6c616e672f4f626a6563743b010001740100124c6a6176612f6c616e672f5468726561643b01000354543b01000d537461636b4d61705461626c650100062854543b29560700430100106a6176612f6c616e672f4f626a656374010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b01008f3c543a4c6a6176612f6c616e672f4f626a6563743b3e4c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b4c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b3e3b01000a536f7572636546696c65010019416e6f6e796d6f75735468726561644c6f63616c2e6a6176610021000800020001002c00010012000b000c0001002e00000002002f000600010005000f0003003000000062000200020000000a2ab700012a2bb50007b10000000300310000000e000300000016000400170009001800320000001600020000000a0033003400000000000a000b000c000100350000001600020000000a0033003600000000000a000b002f000100370000000501000b0000002e0000000200380001002a002b00030030000000590003000200000009bb0008592bb7000db00000000300310000000600010000001b00320000001600020000000900330034000000000009000b000c000100350000001600020000000900330036000000000009000b002f000100370000000501000b0000002e0000000200390004002600150002003000000046000100010000000a2ab40007b900100100b00000000300310000000600010000002000320000000c00010000000a00330034000000350000000c00010000000a003300360000002e00000002003a00010022002300030030000000850002000300000011b800164d2cb6001c9a00082a2bb70020b10000000400310000001200040000002500040026000b00270010002900320000002000030000001100330034000000000011003b003c00010004000d003d003e000200350000001600020000001100330036000000000011003b003f00010040000000080001fc001007001700370000000501003b0000002e00000002004100010014001500020030000000730001000200000017b800164c2bb6001c99000a2ab60024a700072ab70027b00000000400310000000a00020000002d0004002e00320000001600020000001700330034000000040013003d003e000100350000000c00010000001700330036000000400000000c0002fc001207001743070042002e00000002003a1041002a0044000200300000004500020002000000092a2bc00011b60028b00000000300310000000600010000001200320000000c00010000000900330034000000350000000c00010000000900330036000000370000000501000b10000002002e0000000200450046000000020047"; @@ -322,6 +329,27 @@ public final class Utility { return futureArrayFunc; } + public static Executor defaultExecutor() { + return virtualExecutorConsumer == null ? defaultExecutorConsumer : virtualExecutorConsumer; + } + + /** + * 返回第一个不为null的对象 + * + * @param 泛型 + * @param vals 对象集合 + * + * @return 可用对象,没有返回null + */ + public static T orElse(T... vals) { + for (T t : vals) { + if (t != null) { + return t; + } + } + return null; + } + public static void execute(Runnable task) { if (virtualExecutorConsumer != null) { virtualExecutorConsumer.execute(task);