> relationMap = manager.get(poolName);
+ Assert.assertEquals(11, relationMap.size() - defaultRelationSize);
+ // check the number of threads between the group and the thread pool
+ IntStream.rangeClosed(rangeMin, rangeMax).forEach(index -> {
+ String relationKey = String.format("test-group-%s", index);
+ Assert.assertNotNull(relationMap.get(relationKey));
+ Assert.assertEquals(1, relationMap.get(relationKey).size());
+ });
+
+ // instantiate the same group a second time and check the corresponding quantitative relationship
+ IntStream.rangeClosed(defaultIndex, rangeMax).forEach(index -> ExecutorFactory.Managed.newSingleScheduledExecutorService(String.format("test-group-%s", index), threadFactory));
+ // chek group size
+ Assert.assertEquals(11, manager.get(poolName).size() - defaultRelationSize);
+ // check the number of threads between the group and the thread pool
+ IntStream.rangeClosed(rangeMin, rangeMax).forEach(index -> Assert.assertEquals(2, relationMap.get(String.format("test-group-%s", index)).size()));
+ }
+
}
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java
index 011e4148..a33c6b83 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java
@@ -37,6 +37,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
/**
@@ -45,6 +46,12 @@ import java.util.concurrent.atomic.AtomicLong;
@Slf4j
public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor implements DisposableBean {
+ /**
+ * A flag used to indicate whether destroy() method has been called,
+ * after the flag is set to false, calling destroy() method again will not take effect
+ */
+ private final AtomicBoolean active;
+
/**
* Wait for tasks to complete on shutdown
*/
@@ -92,11 +99,22 @@ public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor impl
threadPoolId, new DefaultThreadPoolPluginManager().setPluginComparator(AnnotationAwareOrderComparator.INSTANCE),
corePoolSize, maximumPoolSize, keepAliveTime, unit,
blockingQueue, threadFactory, rejectedExecutionHandler);
- log.info("Initializing ExecutorService {}", threadPoolId);
+ log.info("Initializing ExecutorService '{}'", threadPoolId);
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
// Init default plugins.
new DefaultThreadPoolPluginRegistrar(executeTimeOut, awaitTerminationMillis)
.doRegister(this);
+ this.active = new AtomicBoolean(true);
+ }
+
+ /**
+ * Whether the current instance is in the active state.
+ * It returns false when the xx method is called at least once.
+ *
+ * @return true if current instance is in the active state, false otherwise
+ */
+ public boolean isActive() {
+ return active.get();
}
/**
@@ -104,12 +122,21 @@ public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor impl
*/
@Override
public void destroy() {
+ // instance has been destroyed, not need to call this method again
+ if (!isActive()) {
+ log.warn("Failed to destroy ExecutorService '{}' because it has already been destroyed", getThreadPoolId());
+ return;
+ }
if (isWaitForTasksToCompleteOnShutdown()) {
super.shutdown();
} else {
super.shutdownNow();
}
getThreadPoolPluginManager().clear();
+ log.info("ExecutorService '{}' has been destroyed", getThreadPoolId());
+
+ // modify the flag to false avoid the method being called repeatedly
+ active.set(false);
}
/**
diff --git a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java
index 63d362af..275cd915 100644
--- a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java
+++ b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutorTest.java
@@ -95,7 +95,7 @@ public class DynamicThreadPoolExecutorTest {
});
executor.destroy();
- // waitting for terminated
+ // waiting for terminated
while (!executor.isTerminated()) {
} ;
Assert.assertEquals(2, count.get());
@@ -119,9 +119,9 @@ public class DynamicThreadPoolExecutorTest {
});
executor.destroy();
- // waitting for terminated
+ // waiting for terminated
while (!executor.isTerminated()) {
- } ;
+ }
Assert.assertEquals(1, count.get());
}
@@ -157,4 +157,21 @@ public class DynamicThreadPoolExecutorTest {
Assert.assertFalse(executor.isWaitForTasksToCompleteOnShutdown());
}
+ @Test
+ public void testIsActive() {
+ DynamicThreadPoolExecutor executor = new DynamicThreadPoolExecutor(
+ 1, 1, 1000L, TimeUnit.MILLISECONDS,
+ 1000L, true, 1000L,
+ new ArrayBlockingQueue<>(1), "test", Thread::new, new ThreadPoolExecutor.DiscardOldestPolicy());
+ Assert.assertTrue(executor.isActive());
+
+ // waiting for terminated
+ executor.destroy();
+ while (!executor.isTerminated()) {
+ }
+ Assert.assertFalse(executor.isActive());
+ executor.destroy();
+ Assert.assertFalse(executor.isActive());
+ }
+
}
diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java
index a8329e07..e7c078e3 100644
--- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java
+++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/DingSendMessageHandler.java
@@ -92,13 +92,11 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler {
String title = Objects.equals(notifyConfig.getType(), "CONFIG") ? DING_NOTICE_TITLE : DING_ALARM_TITLE;
String text = robotMessageExecuteDTO.getText();
ArrayList atMobiles = CollectionUtil.newArrayList(notifyConfig.getReceives().split(","));
-
HashMap markdown = new HashMap<>();
markdown.put("title", title);
markdown.put("text", text);
HashMap at = new HashMap<>();
at.put("atMobiles", atMobiles);
-
HashMap markdownJson = new HashMap<>();
markdownJson.put("msgtype", "markdown");
markdownJson.put("markdown", markdown);
@@ -106,18 +104,29 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler {
try {
String responseBody = HttpUtil.post(serverUrl, markdownJson);
DingRobotResponse response = JSONUtil.parseObject(responseBody, DingRobotResponse.class);
- Assert.isTrue(response != null, "response is null");
+ Assert.isTrue(response != null, "Response is null.");
if (response.getErrcode() != 0) {
- log.error("Ding failed to send message,reason : {}", response.errmsg);
+ log.error("Ding failed to send message, reason : {}", response.errmsg);
}
} catch (Exception ex) {
- log.error("Ding failed to send message", ex);
+ log.error("Ding failed to send message.", ex);
}
}
+ /**
+ * Ding robot response.
+ */
@Data
static class DingRobotResponse {
+
+ /**
+ * Error code
+ */
private Long errcode;
+
+ /**
+ * Error message
+ */
private String errmsg;
}
}
diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
index 51edf16c..62467060 100644
--- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
+++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
@@ -21,7 +21,7 @@ import cn.hippo4j.common.api.ThreadPoolCheckAlarm;
import cn.hippo4j.common.api.ThreadPoolConfigChange;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.config.springboot.starter.monitor.ThreadPoolMonitorExecutor;
-import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder;
+import cn.hippo4j.config.springboot.starter.notify.ConfigModeNotifyConfigBuilder;
import cn.hippo4j.config.springboot.starter.refresher.event.AdapterExecutorsRefreshListener;
import cn.hippo4j.config.springboot.starter.refresher.event.DynamicThreadPoolRefreshListener;
import cn.hippo4j.config.springboot.starter.refresher.event.PlatformsRefreshListener;
@@ -77,7 +77,7 @@ public class DynamicThreadPoolAutoConfiguration {
@Bean
public NotifyConfigBuilder notifyConfigBuilder(AlarmControlHandler alarmControlHandler) {
- return new CoreNotifyConfigBuilder(alarmControlHandler, bootstrapConfigProperties);
+ return new ConfigModeNotifyConfigBuilder(alarmControlHandler, bootstrapConfigProperties);
}
@Bean
@@ -105,9 +105,9 @@ public class DynamicThreadPoolAutoConfiguration {
@Bean
@SuppressWarnings("all")
public DynamicThreadPoolRefreshListener hippo4jExecutorsListener(ThreadPoolConfigChange threadPoolConfigChange,
- CoreNotifyConfigBuilder coreNotifyConfigBuilder,
+ ConfigModeNotifyConfigBuilder configModeNotifyConfigBuilder,
Hippo4jBaseSendMessageService hippoBaseSendMessageService) {
- return new DynamicThreadPoolRefreshListener(threadPoolConfigChange, coreNotifyConfigBuilder, hippoBaseSendMessageService);
+ return new DynamicThreadPoolRefreshListener(threadPoolConfigChange, configModeNotifyConfigBuilder, hippoBaseSendMessageService);
}
@Bean
diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java
similarity index 98%
rename from hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java
rename to hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java
index 9dba54a8..7a01ae4e 100644
--- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/CoreNotifyConfigBuilder.java
+++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/notify/ConfigModeNotifyConfigBuilder.java
@@ -32,11 +32,11 @@ import java.util.*;
import java.util.stream.Collectors;
/**
- * Core notify config builder.
+ * Config mode notify config builder.
*/
@AllArgsConstructor
@Slf4j
-public class CoreNotifyConfigBuilder implements NotifyConfigBuilder {
+public class ConfigModeNotifyConfigBuilder implements NotifyConfigBuilder {
private final AlarmControlHandler alarmControlHandler;
diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java
index fe30533c..4ed28af4 100644
--- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java
+++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java
@@ -24,7 +24,7 @@ import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
-import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder;
+import cn.hippo4j.config.springboot.starter.notify.ConfigModeNotifyConfigBuilder;
import cn.hippo4j.config.springboot.starter.support.GlobalCoreThreadPoolManage;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
@@ -60,7 +60,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener changeKeys = new ArrayList<>();
- Map> newDynamicThreadPoolNotifyMap = coreNotifyConfigBuilder.buildSingleNotifyConfig(executorProperties);
+ Map> newDynamicThreadPoolNotifyMap = configModeNotifyConfigBuilder.buildSingleNotifyConfig(executorProperties);
Map> notifyConfigs = hippo4jBaseSendMessageService.getNotifyConfigs();
if (CollectionUtil.isNotEmpty(notifyConfigs)) {
for (Map.Entry> each : newDynamicThreadPoolNotifyMap.entrySet()) {
@@ -183,7 +183,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener> notifyConfig = configBuilder.buildSingleNotifyConfig(executorProperties);
sendMessageService.putPlatform(notifyConfig);
wrapper.setInitFlag(Boolean.TRUE);
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
index 8614c4fc..2650fb11 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java
@@ -52,11 +52,12 @@ import cn.hippo4j.springboot.starter.monitor.ReportingEventExecutor;
import cn.hippo4j.springboot.starter.monitor.collect.RunTimeInfoCollector;
import cn.hippo4j.springboot.starter.monitor.send.MessageSender;
import cn.hippo4j.springboot.starter.monitor.send.http.HttpConnectSender;
-import cn.hippo4j.springboot.starter.notify.ServerNotifyConfigBuilder;
+import cn.hippo4j.springboot.starter.notify.ServerModeNotifyConfigBuilder;
import cn.hippo4j.springboot.starter.remote.HttpAgent;
import cn.hippo4j.springboot.starter.remote.HttpScheduledHealthCheck;
import cn.hippo4j.springboot.starter.remote.ServerHealthCheck;
import cn.hippo4j.springboot.starter.remote.ServerHttpAgent;
+import cn.hippo4j.springboot.starter.support.AdaptedThreadPoolDestroyPostProcessor;
import cn.hippo4j.springboot.starter.support.DynamicThreadPoolConfigService;
import cn.hippo4j.springboot.starter.support.DynamicThreadPoolPostProcessor;
import cn.hippo4j.springboot.starter.support.ThreadPoolPluginRegisterPostProcessor;
@@ -68,6 +69,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.info.BuildProperties;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -114,10 +116,15 @@ public class DynamicThreadPoolAutoConfiguration {
@SuppressWarnings("all")
public DynamicThreadPoolService dynamicThreadPoolConfigService(HttpAgent httpAgent,
ServerHealthCheck serverHealthCheck,
- ServerNotifyConfigBuilder notifyConfigBuilder,
+ ServerModeNotifyConfigBuilder serverModeNotifyConfigBuilder,
Hippo4jBaseSendMessageService hippo4jBaseSendMessageService,
DynamicThreadPoolSubscribeConfig dynamicThreadPoolSubscribeConfig) {
- return new DynamicThreadPoolConfigService(httpAgent, properties, notifyConfigBuilder, hippo4jBaseSendMessageService, dynamicThreadPoolSubscribeConfig);
+ return new DynamicThreadPoolConfigService(httpAgent, properties, serverModeNotifyConfigBuilder, hippo4jBaseSendMessageService, dynamicThreadPoolSubscribeConfig);
+ }
+
+ @Bean
+ public AdaptedThreadPoolDestroyPostProcessor adaptedThreadPoolDestroyPostProcessor(ApplicationContext applicationContext) {
+ return new AdaptedThreadPoolDestroyPostProcessor(applicationContext);
}
@Bean
@@ -198,7 +205,7 @@ public class DynamicThreadPoolAutoConfiguration {
public NotifyConfigBuilder serverNotifyConfigBuilder(HttpAgent httpAgent,
BootstrapProperties properties,
AlarmControlHandler alarmControlHandler) {
- return new ServerNotifyConfigBuilder(httpAgent, properties, alarmControlHandler);
+ return new ServerModeNotifyConfigBuilder(httpAgent, properties, alarmControlHandler);
}
@Bean
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java
similarity index 97%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java
rename to hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java
index 8aeedb98..3cfbe586 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerNotifyConfigBuilder.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/notify/ServerModeNotifyConfigBuilder.java
@@ -41,11 +41,11 @@ import java.util.Objects;
import static cn.hippo4j.common.constant.Constants.BASE_PATH;
/**
- * Server notify config builder.
+ * Server mode notify config builder.
*/
@Slf4j
@AllArgsConstructor
-public class ServerNotifyConfigBuilder implements NotifyConfigBuilder {
+public class ServerModeNotifyConfigBuilder implements NotifyConfigBuilder {
private final HttpAgent httpAgent;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java
new file mode 100644
index 00000000..61b8418d
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/AdaptedThreadPoolDestroyPostProcessor.java
@@ -0,0 +1,91 @@
+/*
+ * 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 cn.hippo4j.springboot.starter.support;
+
+import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
+import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
+import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
+import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapter;
+import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+
+import java.util.Optional;
+
+/**
+ * Adapted thread pool destroy post processor.
+ * The processor is used to destroy the internal {@link DynamicThreadPoolExecutor} instance
+ * in the instance adapted by {@link DynamicThreadPoolAdapter} in the spring context.
+ *
+ * @see DynamicThreadPoolAdapter
+ */
+@RequiredArgsConstructor
+@Slf4j
+public class AdaptedThreadPoolDestroyPostProcessor implements DestructionAwareBeanPostProcessor {
+
+ /**
+ * Application context.
+ */
+ private final ApplicationContext applicationContext;
+
+ /**
+ * If {@link DynamicThreadPoolAdapterChoose#match} method returns true,
+ * try to destroy its internal {@link DynamicThreadPoolExecutor} instance.
+ *
+ * @param bean the bean instance to check
+ * @return {@code true} if {@link DynamicThreadPoolAdapterChoose#match} method returns true, false otherwise
+ * @see DynamicThreadPoolAdapterChoose#match
+ */
+ @Override
+ public boolean requiresDestruction(Object bean) {
+ return DynamicThreadPoolAdapterChoose.match(bean);
+ }
+
+ /**
+ * If the internal {@link DynamicThreadPoolExecutor} instance in the adapted bean is not managed by spring,
+ * call its {@link DynamicThreadPoolExecutor#destroy()} directly.
+ *
+ * @param bean the bean instance to be destroyed
+ * @param beanName the name of the bean
+ * @throws BeansException in case of errors
+ * @see DynamicThreadPoolExecutor#destroy()
+ */
+ @Override
+ public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
+ Optional.ofNullable(DynamicThreadPoolAdapterChoose.unwrap(bean))
+ .map(DynamicThreadPoolExecutor::getThreadPoolId)
+ // the internal thread pool is also managed by spring, no manual destruction required
+ .filter(applicationContext::containsBeanDefinition)
+ .map(GlobalThreadPoolManage::getExecutorService)
+ .ifPresent(executor -> destroyAdaptedThreadPoolExecutor(beanName, executor));
+ }
+
+ private void destroyAdaptedThreadPoolExecutor(String beanName, DynamicThreadPoolWrapper executor) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Destroy internal dynamic thread pool '{}' for bean '{}'", executor.getThreadPoolId(), beanName);
+ }
+ executor.destroy();
+ } catch (Exception e) {
+ log.warn("Failed to destroy internal dynamic thread pool '{}' for bean '{}'", executor.getThreadPoolId(), beanName);
+ }
+ }
+}
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java
index 663b07dc..f648b346 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java
@@ -35,7 +35,7 @@ import cn.hippo4j.message.service.Hippo4jBaseSendMessageService;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import cn.hippo4j.springboot.starter.config.BootstrapProperties;
import cn.hippo4j.springboot.starter.core.DynamicThreadPoolSubscribeConfig;
-import cn.hippo4j.springboot.starter.notify.ServerNotifyConfigBuilder;
+import cn.hippo4j.springboot.starter.notify.ServerModeNotifyConfigBuilder;
import cn.hippo4j.springboot.starter.remote.HttpAgent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -58,7 +58,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer
private final BootstrapProperties properties;
- private final ServerNotifyConfigBuilder notifyConfigBuilder;
+ private final ServerModeNotifyConfigBuilder serverModeNotifyConfigBuilder;
private final Hippo4jBaseSendMessageService hippo4jBaseSendMessageService;
@@ -108,7 +108,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer
registerParameter.getActiveAlarm(),
registerParameter.getCapacityAlarm());
GlobalNotifyAlarmManage.put(registerParameter.getThreadPoolId(), threadPoolNotifyAlarm);
- Map> builderNotify = notifyConfigBuilder.getAndInitNotify(CollectionUtil.newArrayList(registerParameter.getThreadPoolId()));
+ Map> builderNotify = serverModeNotifyConfigBuilder.getAndInitNotify(CollectionUtil.newArrayList(registerParameter.getThreadPoolId()));
hippo4jBaseSendMessageService.putPlatform(builderNotify);
}