diff --git a/common/src/main/java/org/dromara/dynamictp/common/entity/ThreadPoolStats.java b/common/src/main/java/org/dromara/dynamictp/common/entity/ThreadPoolStats.java
index c294765b5a640d7669bfe8b47c7e5a0b2e4dca51..06b4928b135ac3f8a07da5503693867e4abc9131 100644
--- a/common/src/main/java/org/dromara/dynamictp/common/entity/ThreadPoolStats.java
+++ b/common/src/main/java/org/dromara/dynamictp/common/entity/ThreadPoolStats.java
@@ -51,6 +51,11 @@ public class ThreadPoolStats extends Metrics {
*/
private int maximumPoolSize;
+ /**
+ * 空闲时间 (ms)
+ */
+ private long keepAliveTime;
+
/**
* 队列类型
*/
diff --git a/core/src/main/java/org/dromara/dynamictp/core/aware/AwareManager.java b/core/src/main/java/org/dromara/dynamictp/core/aware/AwareManager.java
index 28feee7dc953bdb2d7d88c4052c4dbb9ff677e84..98cb34184ebe521c9b7b4e3b05c39c9e73f7c21a 100644
--- a/core/src/main/java/org/dromara/dynamictp/core/aware/AwareManager.java
+++ b/core/src/main/java/org/dromara/dynamictp/core/aware/AwareManager.java
@@ -96,7 +96,7 @@ public class AwareManager {
public static void beforeExecute(Executor executor, Thread t, Runnable r) {
for (ExecutorAware aware : EXECUTOR_AWARE_LIST) {
try {
- aware.beforeExecute(executor, t, r);
+ r = aware.beforeExecuteWrap(executor, t, r);
} catch (Exception e) {
log.error("DynamicTp aware [{}], enhance beforeExecute error.", aware.getName(), e);
}
@@ -106,7 +106,7 @@ public class AwareManager {
public static void afterExecute(Executor executor, Runnable r, Throwable t) {
for (ExecutorAware aware : EXECUTOR_AWARE_LIST) {
try {
- aware.afterExecute(executor, r, t);
+ r = aware.afterExecuteWrap(executor, r, t);
} catch (Exception e) {
log.error("DynamicTp aware [{}], enhance afterExecute error.", aware.getName(), e);
}
@@ -146,7 +146,7 @@ public class AwareManager {
public static void beforeReject(Runnable r, Executor executor) {
for (ExecutorAware aware : EXECUTOR_AWARE_LIST) {
try {
- aware.beforeReject(r, executor);
+ r = aware.beforeRejectWrap(r, executor);
} catch (Exception e) {
log.error("DynamicTp aware [{}], enhance beforeReject error.", aware.getName(), e);
}
@@ -156,7 +156,7 @@ public class AwareManager {
public static void afterReject(Runnable r, Executor executor) {
for (ExecutorAware aware : EXECUTOR_AWARE_LIST) {
try {
- aware.afterReject(r, executor);
+ r = aware.afterRejectWrap(r, executor);
} catch (Exception e) {
log.error("DynamicTp aware [{}], enhance afterReject error.", aware.getName(), e);
}
diff --git a/core/src/main/java/org/dromara/dynamictp/core/aware/ExecutorAware.java b/core/src/main/java/org/dromara/dynamictp/core/aware/ExecutorAware.java
index 29af266b2c843f1077f875fcb7a8c9092c968ab2..9fe023fc75a21a25117646177a40b6f9fe5c4df7 100644
--- a/core/src/main/java/org/dromara/dynamictp/core/aware/ExecutorAware.java
+++ b/core/src/main/java/org/dromara/dynamictp/core/aware/ExecutorAware.java
@@ -91,6 +91,11 @@ public interface ExecutorAware extends DtpAware {
// default no Operation
}
+ default Runnable beforeExecuteWrap(Executor executor, Thread t, Runnable r) {
+ beforeExecute(executor, t, r);
+ return r;
+ }
+
/**
* enhance afterExecute
*
@@ -102,6 +107,12 @@ public interface ExecutorAware extends DtpAware {
// default no Operation
}
+ default Runnable afterExecuteWrap(Executor executor, Runnable r, Throwable t) {
+ // default no Operation
+ afterExecute(executor, r, t);
+ return r;
+ }
+
/**
* enhance shutdown
*
@@ -139,6 +150,12 @@ public interface ExecutorAware extends DtpAware {
// default no Operation
}
+ default Runnable beforeRejectWrap(Runnable r, Executor executor) {
+ // default no Operation
+ beforeReject(r, executor);
+ return r;
+ }
+
/**
* enhance after reject
* @param r runnable
@@ -147,4 +164,10 @@ public interface ExecutorAware extends DtpAware {
default void afterReject(Runnable r, Executor executor) {
// default no Operation
}
+
+ default Runnable afterRejectWrap(Runnable r, Executor executor) {
+ // default no Operation
+ afterReject(r, executor);
+ return r;
+ }
}
diff --git a/core/src/main/java/org/dromara/dynamictp/core/converter/ExecutorConverter.java b/core/src/main/java/org/dromara/dynamictp/core/converter/ExecutorConverter.java
index 70af16371435bbfc738c438e372841b06c82d6c5..48d3333218c34f1c144593ade56d5f232efc7a3d 100644
--- a/core/src/main/java/org/dromara/dynamictp/core/converter/ExecutorConverter.java
+++ b/core/src/main/java/org/dromara/dynamictp/core/converter/ExecutorConverter.java
@@ -97,6 +97,7 @@ public class ExecutorConverter {
poolStats.setCompletedTaskCount(executor.getCompletedTaskCount());
poolStats.setWaitTaskCount(executor.getQueueSize());
poolStats.setRejectHandlerName(executor.getRejectHandlerType());
+ poolStats.setKeepAliveTime(executor.getKeepAliveTime(TimeUnit.MILLISECONDS));
return poolStats;
}
}
diff --git a/core/src/main/java/org/dromara/dynamictp/core/monitor/collector/jmx/JMXCollector.java b/core/src/main/java/org/dromara/dynamictp/core/monitor/collector/jmx/JMXCollector.java
index 1a9578130588a90b73593bdf83adaf481aa549d9..366aab46561fb12d6d87bdbe941388a24dcb3e4e 100644
--- a/core/src/main/java/org/dromara/dynamictp/core/monitor/collector/jmx/JMXCollector.java
+++ b/core/src/main/java/org/dromara/dynamictp/core/monitor/collector/jmx/JMXCollector.java
@@ -21,14 +21,11 @@ import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.em.CollectorTypeEnum;
import org.dromara.dynamictp.common.entity.ThreadPoolStats;
import org.dromara.dynamictp.core.monitor.collector.AbstractCollector;
-import org.springframework.beans.BeanUtils;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
/**
* ThreadPoolStatsInfo related
diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index 3cc5d53bf9a10ee0272cf1106e465bfc400484a3..83b9a2250914e070f9feefded7ef90064aa81a5e 100644
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -426,6 +426,12 @@
${revision}
+
+ org.dromara.dynamictp
+ dynamic-tp-extension-agent
+ ${revision}
+
+
org.dromara.dynamictp
dynamic-tp-extension-notify-email
diff --git a/extension/extension-agent/pom.xml b/extension/extension-agent/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..26585b894da4d0f1a6e63bb6a00760ece736aafd
--- /dev/null
+++ b/extension/extension-agent/pom.xml
@@ -0,0 +1,14 @@
+
+ 4.0.0
+
+ org.dromara.dynamictp
+ dynamic-tp-extension
+ ${revision}
+ ../pom.xml
+
+ dynamic-tp-extension-agent
+
+
+
+
diff --git a/extension/extension-agent/src/main/java/org/dromara/dynamictp/core/aware/AgentAware.java b/extension/extension-agent/src/main/java/org/dromara/dynamictp/core/aware/AgentAware.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc965e5e5c55cde3cc2867a4c31cc1acb1286452
--- /dev/null
+++ b/extension/extension-agent/src/main/java/org/dromara/dynamictp/core/aware/AgentAware.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.dromara.dynamictp.core.aware;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ArrayUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.dynamictp.core.support.task.runnable.DtpRunnable;
+
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
+
+import static org.dromara.dynamictp.common.constant.DynamicTpConst.DTP_EXECUTE_ENHANCED;
+import static org.dromara.dynamictp.common.constant.DynamicTpConst.FALSE_STR;
+
+/**
+ * deal agent wrapper
+ * @author txbao
+ */
+@Slf4j
+public class AgentAware extends TaskStatAware {
+ @Override
+ public int getOrder() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public String getName() {
+ return "agent";
+ }
+
+ /**
+ * dtpRunnableCache key -> Runnable value -> DtpRunnable
+ */
+ private final Map> dtpRunnableCache = new ConcurrentHashMap<>();
+
+ private DtpRunnable determineDtpRunnable(List conditionalFields, Runnable r) throws IllegalAccessException {
+
+ for (Field field : conditionalFields) {
+ if (Objects.isNull(field)) {
+ continue;
+ }
+
+ field.setAccessible(true);
+ Runnable o = (Runnable) field.get(r);
+ if (o instanceof DtpRunnable) {
+ return (DtpRunnable) o;
+ }
+ // 纵向查找
+ DtpRunnable dtpRunnable = getDtpRunnable(o.getClass(), o);
+ if (dtpRunnable != null) {
+ return dtpRunnable;
+ }
+ }
+ return null;
+ }
+
+ private DtpRunnable getDtpRunnable(Class extends Runnable> rClass, Runnable r) throws IllegalAccessException {
+ while (Runnable.class.isAssignableFrom(rClass)) {
+ Field[] declaredFields = rClass.getDeclaredFields();
+ if (ArrayUtil.isNotEmpty(declaredFields)) {
+ List conditionFields = Arrays.stream(declaredFields)
+ .filter(ele -> Runnable.class.isAssignableFrom(ele.getType()))
+ .collect(Collectors.toList());
+ if (CollectionUtil.isNotEmpty(conditionFields)) {
+ DtpRunnable dtpRunnable = determineDtpRunnable(conditionFields, r);
+ if (Objects.nonNull(dtpRunnable)) {
+ return dtpRunnable;
+ }
+ }
+ }
+ if (!Runnable.class.isAssignableFrom(rClass.getSuperclass())) {
+ break;
+ }
+ rClass = (Class extends Runnable>) rClass.getSuperclass();
+ }
+ return null;
+ }
+
+ private Runnable getDtpRunnableInstance(Runnable r) {
+ if (r instanceof DtpRunnable) {
+ return r;
+ }
+
+ DtpRunnable dtpRunnable = null;
+ Class extends Runnable> rClass = r.getClass();
+ try {
+ dtpRunnable = getDtpRunnable(rClass, r);
+ } catch (IllegalAccessException e) {
+ log.error("getDtpRunnable Error", e);
+ }
+
+ if (dtpRunnable == null) {
+ if (log.isWarnEnabled()) {
+ log.warn("DynamicTp aware [{}], can not find DtpRunnable.", getName());
+ }
+ return r;
+ }
+
+ return dtpRunnable;
+ }
+
+ @Override
+ public Runnable beforeExecuteWrap(Executor executor, Thread t, Runnable r) {
+ Runnable runnableWrap = getDtpRunnableInstance(r);
+ if (runnableWrap instanceof DtpRunnable) {
+ dtpRunnableCache.put(r, new SoftReference<>((DtpRunnable) runnableWrap));
+ } else {
+ // 被封装的wrapper没有找到DtpRunnable对象,那么就关闭某些监控指标,防止内存溢出
+ System.setProperty(DTP_EXECUTE_ENHANCED, FALSE_STR);
+ }
+ return runnableWrap;
+ }
+
+ @Override
+ public Runnable afterExecuteWrap(Executor executor, Runnable r, Throwable t) {
+ SoftReference remove = dtpRunnableCache.remove(r);
+ if (remove != null) {
+ return remove.get();
+ }
+ return getDtpRunnableInstance(r);
+ }
+
+ @Override
+ public Runnable beforeRejectWrap(Runnable r, Executor executor) {
+ SoftReference remove = dtpRunnableCache.remove(r);
+ if (remove != null) {
+ return remove.get();
+ }
+ return getDtpRunnableInstance(r);
+ }
+
+ @Override
+ public Runnable afterRejectWrap(Runnable r, Executor executor) {
+ SoftReference remove = dtpRunnableCache.remove(r);
+ if (remove != null) {
+ return remove.get();
+ }
+ return getDtpRunnableInstance(r);
+ }
+}
diff --git a/extension/extension-agent/src/main/resources/META-INF/services/org.dromara.dynamictp.core.aware.ExecutorAware b/extension/extension-agent/src/main/resources/META-INF/services/org.dromara.dynamictp.core.aware.ExecutorAware
new file mode 100644
index 0000000000000000000000000000000000000000..064e5f138ce1b73250c62f6f64e5ec3d4c79a364
--- /dev/null
+++ b/extension/extension-agent/src/main/resources/META-INF/services/org.dromara.dynamictp.core.aware.ExecutorAware
@@ -0,0 +1 @@
+org.dromara.dynamictp.core.aware.AgentAware
\ No newline at end of file
diff --git a/extension/pom.xml b/extension/pom.xml
index 0941b815a277dde370a09da263042103eeb516ef..a2d20349dfc3917c555300777e54df6e26c8f01a 100644
--- a/extension/pom.xml
+++ b/extension/pom.xml
@@ -17,6 +17,7 @@
extension-notify-email
extension-opentelemetry
extension-notify-yunzhijia
+ extension-agent
diff --git a/starter/starter-adapter/starter-adapter-webserver/src/main/java/org/dromara/dynamictp/starter/adapter/webserver/undertow/EnhancedQueueExecutorProxy.java b/starter/starter-adapter/starter-adapter-webserver/src/main/java/org/dromara/dynamictp/starter/adapter/webserver/undertow/EnhancedQueueExecutorProxy.java
index f34d27d708fc59fe8bed7e6ccda722c2deaf6a23..b0dcf9faabdd58d013988fda873027b46dae4532 100644
--- a/starter/starter-adapter/starter-adapter-webserver/src/main/java/org/dromara/dynamictp/starter/adapter/webserver/undertow/EnhancedQueueExecutorProxy.java
+++ b/starter/starter-adapter/starter-adapter-webserver/src/main/java/org/dromara/dynamictp/starter/adapter/webserver/undertow/EnhancedQueueExecutorProxy.java
@@ -18,9 +18,12 @@
package org.dromara.dynamictp.starter.adapter.webserver.undertow;
import org.dromara.dynamictp.core.aware.AwareManager;
+import org.dromara.dynamictp.core.aware.TaskEnhanceAware;
import org.dromara.dynamictp.core.support.task.runnable.EnhancedRunnable;
+import org.dromara.dynamictp.core.support.task.wrapper.TaskWrapper;
import org.jboss.threads.EnhancedQueueExecutor;
+import java.util.List;
import java.util.concurrent.RejectedExecutionException;
/**
@@ -30,7 +33,9 @@ import java.util.concurrent.RejectedExecutionException;
* @since 1.1.4
**/
@SuppressWarnings("all")
-public class EnhancedQueueExecutorProxy extends EnhancedQueueExecutor {
+public class EnhancedQueueExecutorProxy extends EnhancedQueueExecutor implements TaskEnhanceAware {
+
+ private List taskWrappers;
public EnhancedQueueExecutorProxy(final Builder builder) {
super(builder);
@@ -49,19 +54,29 @@ public class EnhancedQueueExecutorProxy extends EnhancedQueueExecutor {
@Override
public void execute(Runnable runnable) {
- EnhancedRunnable enhanceTask = EnhancedRunnable.of(runnable, this);
- AwareManager.execute(this, enhanceTask);
+ Runnable enhancedTask = getEnhancedTask(EnhancedRunnable.of(runnable, this));
+ AwareManager.execute(this, enhancedTask);
try {
- super.execute(enhanceTask);
+ super.execute(enhancedTask);
} catch (Throwable e) {
Throwable[] suppressedExceptions = e.getSuppressed();
for (Throwable t : suppressedExceptions) {
if (t instanceof RejectedExecutionException) {
- AwareManager.beforeReject(enhanceTask, this);
+ AwareManager.beforeReject(enhancedTask, this);
return;
}
}
throw e;
}
}
+
+ @Override
+ public List getTaskWrappers() {
+ return this.taskWrappers;
+ }
+
+ @Override
+ public void setTaskWrappers(List taskWrappers) {
+ this.taskWrappers = taskWrappers;
+ }
}
diff --git a/test/test-extension/pom.xml b/test/test-extension/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..42d887aaf363cd789ea83452f445a37492070dec
--- /dev/null
+++ b/test/test-extension/pom.xml
@@ -0,0 +1,37 @@
+
+ 4.0.0
+
+ org.dromara.dynamictp
+ dynamic-tp-all
+ ${revision}
+ ../../pom.xml
+
+
+ dynamic-tp-test-extension
+ jar
+
+ test-extension
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+ test
+
+
+
+ org.dromara.dynamictp
+ dynamic-tp-extension-agent
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..89688a5495e69f4a006b19acf6362a7b37463fb0
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java
@@ -0,0 +1,110 @@
+package org.dromara.dynamictp.agent;
+
+import org.dromara.dynamictp.core.aware.AgentAware;
+import org.dromara.dynamictp.core.support.task.runnable.DtpRunnable;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class AgentAwareTest {
+
+ @Test
+ public void testDirectOnlyOneDtpRunnable() throws InvocationTargetException, IllegalAccessException {
+ Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class);
+ Assertions.assertNotNull(getDtpRunnableInstance);
+
+ getDtpRunnableInstance.setAccessible(true);
+
+ Runnable runnable = () -> {
+
+ };
+
+
+ MyAgentWrapper myAgentWrapper = new MyAgentWrapper(runnable, new Object());
+ Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentWrapper);
+ Assertions.assertTrue(result == myAgentWrapper);
+
+ DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test");
+ myAgentWrapper = new MyAgentWrapper(dtpRunnable, new Object());
+ result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentWrapper);
+ Assertions.assertNotNull(dtpRunnable == result);
+ }
+
+ @Test
+ public void testDirectTwoRunnable() throws InvocationTargetException, IllegalAccessException {
+ Runnable runnable = () -> {
+
+ };
+ DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test");
+ MyAgentWrapperTwoRunnable myAgentWrapper = new MyAgentWrapperTwoRunnable(dtpRunnable, runnable, "test");
+
+ Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class);
+ Assertions.assertNotNull(getDtpRunnableInstance);
+ getDtpRunnableInstance.setAccessible(true);
+
+ Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentWrapper);
+ Assertions.assertTrue(result == dtpRunnable);
+
+ myAgentWrapper = new MyAgentWrapperTwoRunnable(runnable, dtpRunnable, "test");
+ result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentWrapper);
+ Assertions.assertTrue(result == dtpRunnable);
+ }
+
+ @Test
+ public void testNotDirectRunnable() throws InvocationTargetException, IllegalAccessException {
+ Runnable runnable = () -> {
+
+ };
+ DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test");
+ MyAgentWrapper myAgentWrapper = new MyAgentWrapper(dtpRunnable, new Object());
+
+ MyAgentTwoPathRunnableWrapper twoPathRunnableWrapper = new MyAgentTwoPathRunnableWrapper(myAgentWrapper, new Object());
+ Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class);
+ Assertions.assertNotNull(getDtpRunnableInstance);
+ getDtpRunnableInstance.setAccessible(true);
+
+ Object result = getDtpRunnableInstance.invoke(new AgentAware(), twoPathRunnableWrapper);
+ Assertions.assertTrue(result == dtpRunnable);
+ }
+
+ @Test
+ public void testExtendRunnable() throws InvocationTargetException, IllegalAccessException {
+ Runnable runnable = () -> {
+
+ };
+ DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test");
+ MyAgentWrapper myAgentWrapper = new MyAgentWrapper(dtpRunnable, new Object());
+ MyAgentWrapperChild myAgentWrapperChild = new MyAgentWrapperChild(myAgentWrapper, new Object());
+
+ Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class);
+ Assertions.assertNotNull(getDtpRunnableInstance);
+ getDtpRunnableInstance.setAccessible(true);
+
+ Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentWrapperChild);
+ Assertions.assertTrue(result == dtpRunnable);
+ }
+
+ @Test
+ public void testDeepRunnable() throws InvocationTargetException, IllegalAccessException {
+ Runnable runnable = () -> {
+
+ };
+ DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test");
+ MyAgentWrapper myAgentWrapper = new MyAgentWrapper(runnable, new Object());
+ MyAgentWrapper myAgentWrapperDtpRunnable = new MyAgentWrapper(dtpRunnable, new Object());
+ MyAgentWrapperChild myAgentWrapperChild = new MyAgentWrapperChild(myAgentWrapperDtpRunnable, new Object());
+
+ MyAgentTwoPathRunnableChildWrapper myAgentTwoPathRunnableChildWrapper = new MyAgentTwoPathRunnableChildWrapper(myAgentWrapperChild,
+ myAgentWrapper, new Object());
+
+ Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class);
+ Assertions.assertNotNull(getDtpRunnableInstance);
+ getDtpRunnableInstance.setAccessible(true);
+ Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentTwoPathRunnableChildWrapper);
+ Assertions.assertTrue(result == dtpRunnable);
+ }
+
+}
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableChildWrapper.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableChildWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f7e783cb30888da61dff6a78ebe0aee846dcd44
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableChildWrapper.java
@@ -0,0 +1,21 @@
+package org.dromara.dynamictp.agent;
+
+public class MyAgentTwoPathRunnableChildWrapper implements Runnable {
+
+ private MyAgentWrapperChild myAgentWrapperChild;
+
+ private MyAgentWrapper myAgentWrapper;
+
+ private Object busi;
+
+ public MyAgentTwoPathRunnableChildWrapper(MyAgentWrapperChild myAgentWrapperChild, MyAgentWrapper myAgentWrapper, Object busi) {
+ this.myAgentWrapperChild = myAgentWrapperChild;
+ this.myAgentWrapper = myAgentWrapper;
+ this.busi = busi;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("MyAgentTwoPathRunnableChildWrapper");
+ }
+}
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableWrapper.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c7c622d56a56ef3085ab573466ba750b0e7ec81
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableWrapper.java
@@ -0,0 +1,24 @@
+package org.dromara.dynamictp.agent;
+
+public class MyAgentTwoPathRunnableWrapper implements Runnable {
+
+ private final MyAgentWrapper myAgentWrapper;
+
+ private final Object busiObj;
+
+ public MyAgentTwoPathRunnableWrapper(MyAgentWrapper myAgentWrapper, Object busiObj) {
+ this.myAgentWrapper = myAgentWrapper;
+ this.busiObj = busiObj;
+ }
+
+
+ @Override
+ public void run() {
+ System.out.println("before");
+ try {
+ myAgentWrapper.run();
+ } finally {
+ System.out.println("finally");
+ }
+ }
+}
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapper.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..56edb3a8d98dd37fe1967bfa4d776b84b7743be1
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapper.java
@@ -0,0 +1,23 @@
+package org.dromara.dynamictp.agent;
+
+public class MyAgentWrapper implements Runnable {
+
+ private Runnable runnable;
+
+ private Object busiObj;
+
+ public MyAgentWrapper(Runnable runnable, Object busiObj) {
+ this.runnable = runnable;
+ this.busiObj = busiObj;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("before");
+ try {
+ runnable.run();
+ } finally {
+ System.out.println("finally");
+ }
+ }
+}
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperChild.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperChild.java
new file mode 100644
index 0000000000000000000000000000000000000000..44919ceaeda21aaba2b6d3825e7883f514d21f74
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperChild.java
@@ -0,0 +1,12 @@
+package org.dromara.dynamictp.agent;
+
+public class MyAgentWrapperChild extends MyAgentWrapper {
+ public MyAgentWrapperChild(MyAgentWrapper runnable, Object busiObj) {
+ super(runnable, busiObj);
+ }
+
+ @Override
+ public void run() {
+ System.out.println("MyAgentWrapperChild");
+ }
+}
diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperTwoRunnable.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperTwoRunnable.java
new file mode 100644
index 0000000000000000000000000000000000000000..b63d9f404be63a4c4c136e23d18f2360833b1ab0
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperTwoRunnable.java
@@ -0,0 +1,27 @@
+package org.dromara.dynamictp.agent;
+
+public class MyAgentWrapperTwoRunnable implements Runnable {
+
+ private Runnable r1;
+
+ private Runnable r2;
+
+ private Object busiObj;
+
+ public MyAgentWrapperTwoRunnable(Runnable r1, Runnable r2, Object busiObj) {
+ this.r1 = r1;
+ this.r2 = r2;
+ this.busiObj = busiObj;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("before");
+ try {
+ r1.run();
+ r2.run();
+ } finally {
+ System.out.println("after");
+ }
+ }
+}