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 c294765b5..06b4928b1 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 28feee7dc..98cb34184 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 static void execute(Executor executor, Runnable r) {
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 static void beforeExecute(Executor executor, Thread t, Runnable r) {
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 static void terminated(Executor executor) {
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 static void beforeReject(Runnable r, Executor executor) {
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 29af266b2..56e492bf1 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 @@ default void beforeExecute(Executor executor, Thread t, Runnable r) {
// default no Operation
}
+ default Runnable beforeExecuteWrap(Executor executor, Thread t, Runnable r) {
+ beforeExecute(executor, t, r);
+ return r;
+ }
+
/**
* enhance afterExecute
*
@@ -102,6 +107,11 @@ default void afterExecute(Executor executor, Runnable r, Throwable t) {
// default no Operation
}
+ default Runnable afterExecuteWrap(Executor executor, Runnable r, Throwable t) {
+ afterExecute(executor, r, t);
+ return r;
+ }
+
/**
* enhance shutdown
*
@@ -139,6 +149,11 @@ default void beforeReject(Runnable r, Executor executor) {
// default no Operation
}
+ default Runnable beforeRejectWrap(Runnable r, Executor executor) {
+ beforeReject(r, executor);
+ return r;
+ }
+
/**
* enhance after reject
* @param r runnable
@@ -147,4 +162,9 @@ default void beforeReject(Runnable r, Executor executor) {
default void afterReject(Runnable r, Executor executor) {
// default no Operation
}
+
+ default Runnable afterRejectWrap(Runnable r, Executor executor) {
+ 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 70af16371..48d333321 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 @@ private static ThreadPoolStats convertCommon(ExecutorAdapter> executor) {
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 1a9578130..366aab465 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 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 3cc5d53bf..ba00b1c4e 100644
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -12,7 +12,7 @@
https://github.com/yanhom1314/dynamic-tp
- 1.1.7
+ 1.1.8-beta
UTF-8
1.18.24
@@ -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 000000000..26585b894
--- /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 000000000..f456db816
--- /dev/null
+++ b/extension/extension-agent/src/main/java/org/dromara/dynamictp/core/aware/AgentAware.java
@@ -0,0 +1,151 @@
+/*
+ * 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.util.ArrayUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+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
+@SuppressWarnings("all")
+public class AgentAware extends TaskStatAware {
+
+ /**
+ * dtpRunnableCache key -> Runnable value -> DtpRunnable
+ */
+ private final Map> dtpRunnableCache = new ConcurrentHashMap<>();
+
+ @Override
+ public int getOrder() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public String getName() {
+ return "agent";
+ }
+
+ 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 (CollectionUtils.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);
+ }
+}
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 000000000..064e5f138
--- /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/extension-skywalking/pom.xml b/extension/extension-skywalking/pom.xml
index 70fb7469e..019485e91 100644
--- a/extension/extension-skywalking/pom.xml
+++ b/extension/extension-skywalking/pom.xml
@@ -21,11 +21,6 @@
org.slf4j
slf4j-api
-
-
- org.dromara.dynamictp
- dynamic-tp-jvmti-runtime
-
diff --git a/extension/extension-skywalking/src/main/java/org/dromara/dynamictp/extension/skywalking/init/SwInitializer.java b/extension/extension-skywalking/src/main/java/org/dromara/dynamictp/extension/skywalking/init/SwInitializer.java
deleted file mode 100644
index ff83ffd95..000000000
--- a/extension/extension-skywalking/src/main/java/org/dromara/dynamictp/extension/skywalking/init/SwInitializer.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.extension.skywalking.init;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.dromara.dynamictp.core.support.init.DtpInitializer;
-import org.dromara.dynamictp.jvmti.JVMTI;
-
-import java.util.List;
-
-import static org.dromara.dynamictp.common.constant.DynamicTpConst.DTP_EXECUTE_ENHANCED;
-import static org.dromara.dynamictp.common.constant.DynamicTpConst.FALSE_STR;
-
-/**
- * SwInitializer related
- *
- * @author yanhom
- * @since 1.1.6
- */
-@Slf4j
-public class SwInitializer implements DtpInitializer {
-
- private static final String SW_AGENT_CLASS_LOADER = "org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader";
-
- private static final String SW_RUNNABLE_WRAPPER = "org.apache.skywalking.apm.plugin.wrapper.SwRunnableWrapper";
-
- private static final String SW_CALLABLE_WRAPPER = "org.apache.skywalking.apm.plugin.wrapper.SwCallableWrapper";
-
- @Override
- public String getName() {
- return "SwInitializer";
- }
-
- @Override
- public void init() {
- try {
- List classLoaders = JVMTI.getInstances(ClassLoader.class);
- if (CollectionUtils.isEmpty(classLoaders)) {
- return;
- }
- for (ClassLoader cl : classLoaders) {
- if (!SW_AGENT_CLASS_LOADER.equals(cl.getClass().getName())) {
- continue;
- }
- if (conditionOnClass(SW_RUNNABLE_WRAPPER, cl) || conditionOnClass(SW_CALLABLE_WRAPPER, cl)) {
- System.setProperty(DTP_EXECUTE_ENHANCED, FALSE_STR);
- log.warn("DynamicTp init, disable enhancement for the execute method " +
- "in the presence of the skywalking threadpool plugin.");
- return;
- }
- }
- } catch (Throwable e) {
- log.error("DynamicTp {} init failed", getName(), e);
- }
- }
-
- private boolean conditionOnClass(String className, ClassLoader classLoader) {
- try {
- Class.forName(className, false, classLoader);
- return true;
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
-}
diff --git a/extension/extension-skywalking/src/main/resources/META-INF/services/org.dromara.dynamictp.core.support.init.DtpInitializer b/extension/extension-skywalking/src/main/resources/META-INF/services/org.dromara.dynamictp.core.support.init.DtpInitializer
deleted file mode 100644
index aa2e33bdc..000000000
--- a/extension/extension-skywalking/src/main/resources/META-INF/services/org.dromara.dynamictp.core.support.init.DtpInitializer
+++ /dev/null
@@ -1 +0,0 @@
-org.dromara.dynamictp.extension.skywalking.init.SwInitializer
\ No newline at end of file
diff --git a/extension/pom.xml b/extension/pom.xml
index 0941b815a..a2d20349d 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/pom.xml b/pom.xml
index 0e67e111e..10417deba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
https://github.com/yanhom1314/dynamic-tp
- 1.1.7
+ 1.1.8-beta
8
8
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 f34d27d70..b0dcf9faa 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 @@
* @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 EnhancedQueueExecutorProxy(final EnhancedQueueExecutor executor) {
@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/pom.xml b/test/pom.xml
index af7a147e9..0423f3252 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -17,6 +17,7 @@
test-core
test-logging
test-configcenter
+ test-extension
diff --git a/test/test-extension/pom.xml b/test/test-extension/pom.xml
new file mode 100644
index 000000000..42d887aaf
--- /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 000000000..7525b188f
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.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 000000000..f76d06bf7
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableChildWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * 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.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 000000000..0f3172661
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentTwoPathRunnableWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * 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.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 000000000..0217e03bd
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.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 000000000..91117d315
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperChild.java
@@ -0,0 +1,29 @@
+/*
+ * 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.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 000000000..c93c647dd
--- /dev/null
+++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentWrapperTwoRunnable.java
@@ -0,0 +1,44 @@
+/*
+ * 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.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");
+ }
+ }
+}