diff --git a/hippo4j-core/pom.xml b/hippo4j-core/pom.xml
index 7b146444..0f127001 100644
--- a/hippo4j-core/pom.xml
+++ b/hippo4j-core/pom.xml
@@ -22,6 +22,18 @@
cn.hippo4j
hippo4j-common
+
+
+ com.aliyun
+ alibaba-dingtalk-service-sdk
+
+
+
+ log4j
+ log4j
+
+
+
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java
new file mode 100644
index 00000000..ee1bc235
--- /dev/null
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java
@@ -0,0 +1,53 @@
+package cn.hippo4j.core.config;
+
+/**
+ * Bootstrap properties interface.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 19:01
+ */
+public interface BootstrapPropertiesInterface {
+
+ /**
+ * Get enable.
+ *
+ * @return
+ */
+ Boolean getEnable();
+
+ /**
+ * Get username.
+ *
+ * @return
+ */
+ String getUsername();
+
+ /**
+ * Get password.
+ *
+ * @return
+ */
+ String getPassword();
+
+ /**
+ * Get namespace.
+ *
+ * @return
+ */
+ String getNamespace();
+
+ /**
+ * Get item id.
+ *
+ * @return
+ */
+ String getItemId();
+
+ /**
+ * Get server addr.
+ *
+ * @return
+ */
+ String getServerAddr();
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java
similarity index 91%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java
index aaa5218a..abe84448 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.core;
+package cn.hippo4j.core.config;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java
similarity index 95%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java
index 5c134ed6..45724025 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.config;
+package cn.hippo4j.core.config;
import cn.hippo4j.core.toolkit.inet.InetUtils;
import cn.hippo4j.core.toolkit.inet.InetUtilsProperties;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java
similarity index 95%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java
index bb31deaf..f269ffe0 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java
@@ -1,8 +1,8 @@
-package cn.hippo4j.starter.enable;
+package cn.hippo4j.core.enable;
import cn.hippo4j.common.toolkit.StringUtil;
-import cn.hippo4j.starter.config.BootstrapProperties;
-import cn.hippo4j.starter.core.ConfigEmptyException;
+import cn.hippo4j.core.config.BootstrapPropertiesInterface;
+import cn.hippo4j.core.config.ConfigEmptyException;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -20,7 +20,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
public class BeforeCheckConfiguration {
@Bean
- public BeforeCheckConfiguration.BeforeCheck dynamicThreadPoolBeforeCheckBean(@Autowired(required = false) BootstrapProperties properties,
+ public BeforeCheckConfiguration.BeforeCheck dynamicThreadPoolBeforeCheckBean(@Autowired(required = false) BootstrapPropertiesInterface properties,
ConfigurableEnvironment environment) {
if (properties != null && properties.getEnable()) {
String username = properties.getUsername();
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java
similarity index 91%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java
index 739ac226..a892a23a 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.enable;
+package cn.hippo4j.core.enable;
import org.springframework.context.annotation.Import;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java
similarity index 91%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java
index 5d3d0da1..2daee96d 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.enable;
+package cn.hippo4j.core.enable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java
similarity index 91%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java
index 7c17d8c2..34529adc 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.core;
+package cn.hippo4j.core.executor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java
index 2d9c939b..9869e484 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java
@@ -35,10 +35,10 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
@Value("${spring.profiles.active:UNKNOWN}")
private String active;
- @Value("${spring.dynamic.thread-pool.item-id}")
+ @Value("${spring.dynamic.thread-pool.item-id:}")
private String itemId;
- @Value("${spring.application.name}")
+ @Value("${spring.application.name:UNKNOWN}")
private String applicationName;
@Value("${spring.dynamic.thread-pool.check-state-interval:5}")
@@ -107,7 +107,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
boolean isSend = threadPoolNotifyAlarm.getIsAlarm()
- && divide > threadPoolNotifyAlarm.getLivenessAlarm();
+ && divide > threadPoolNotifyAlarm.getActiveAlarm();
if (isSend) {
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor);
alarmNotifyRequest.setThreadPoolId(threadPoolId);
@@ -123,7 +123,6 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
public void checkPoolRejectedAlarm(String threadPoolId) {
ThreadPoolExecutor threadPoolExecutor = GlobalThreadPoolManage.getExecutorService(threadPoolId).getExecutor();
checkPoolRejectedAlarm(threadPoolId, threadPoolExecutor);
-
}
/**
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java
index f14cd514..c136c0e4 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java
@@ -84,7 +84,7 @@ public class GlobalThreadPoolManage {
* @return
*/
public static List listThreadPoolId() {
- return Lists.newArrayList(POOL_PARAMETER.keySet());
+ return Lists.newArrayList(EXECUTOR_MAP.keySet());
}
/**
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java
index 54f6afdd..1ba4a6ae 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java
@@ -12,6 +12,12 @@ import java.util.concurrent.TimeUnit;
*/
public class CommonDynamicThreadPool {
+ /**
+ * Get instance.
+ *
+ * @param threadPoolId
+ * @return
+ */
public static DynamicThreadPoolExecutor getInstance(String threadPoolId) {
DynamicThreadPoolExecutor poolExecutor = (DynamicThreadPoolExecutor) ThreadPoolBuilder.builder()
.dynamicPool()
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java
index 0552ed04..389b3fb9 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java
@@ -1,13 +1,14 @@
package cn.hippo4j.core.executor.support;
-import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader;
import cn.hippo4j.core.spi.CustomBlockingQueue;
+import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.*;
+import java.util.stream.Stream;
/**
* Queue type enum.
@@ -65,6 +66,48 @@ public enum QueueTypeEnum {
DynamicThreadPoolServiceLoader.register(CustomBlockingQueue.class);
}
+ /**
+ * Create blocking queue.
+ *
+ * @param blockingQueueName
+ * @param capacity
+ * @return
+ */
+ public static BlockingQueue createBlockingQueue(String blockingQueueName, Integer capacity) {
+ BlockingQueue blockingQueue = null;
+ QueueTypeEnum queueTypeEnum = Stream.of(QueueTypeEnum.values())
+ .filter(each -> Objects.equals(each.name, blockingQueueName))
+ .findFirst()
+ .orElse(null);
+
+ if (queueTypeEnum != null) {
+ blockingQueue = createBlockingQueue(queueTypeEnum.type, capacity);
+ if (Objects.equals(blockingQueue.getClass().getSimpleName(), blockingQueueName)) {
+ return blockingQueue;
+ }
+ }
+
+ Collection customBlockingQueues = DynamicThreadPoolServiceLoader
+ .getSingletonServiceInstances(CustomBlockingQueue.class);
+ blockingQueue = Optional.ofNullable(blockingQueue)
+ .orElseGet(
+ () -> customBlockingQueues.stream()
+ .filter(each -> Objects.equals(blockingQueueName, each.getName()))
+ .map(each -> each.generateBlockingQueue())
+ .findFirst()
+ .orElseGet(() -> {
+ int temCapacity = capacity;
+ if (capacity == null || capacity <= 0) {
+ temCapacity = 1024;
+ }
+
+ return new LinkedBlockingQueue(temCapacity);
+ })
+ );
+
+ return blockingQueue;
+ }
+
/**
* Create blocking queue.
*
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java
index 66fc0f4f..f8e995d8 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java
@@ -21,45 +21,51 @@ public enum RejectedTypeEnum {
/**
* 被拒绝任务的程序由主线程执行
*/
- CALLER_RUNS_POLICY(1, new ThreadPoolExecutor.CallerRunsPolicy()),
+ CALLER_RUNS_POLICY(1, "CallerRunsPolicy", new ThreadPoolExecutor.CallerRunsPolicy()),
/**
* 被拒绝任务的处理程序, 抛出异常
*/
- ABORT_POLICY(2, new ThreadPoolExecutor.AbortPolicy()),
+ ABORT_POLICY(2, "AbortPolicy", new ThreadPoolExecutor.AbortPolicy()),
/**
* 被拒绝任务的处理程序, 默默地丢弃被拒绝的任务。
*/
- DISCARD_POLICY(3, new ThreadPoolExecutor.DiscardPolicy()),
+ DISCARD_POLICY(3, "DiscardPolicy", new ThreadPoolExecutor.DiscardPolicy()),
/**
* 被拒绝任务的处理程序, 它丢弃最早的未处理请求, 然后重试
*/
- DISCARD_OLDEST_POLICY(4, new ThreadPoolExecutor.DiscardOldestPolicy()),
+ DISCARD_OLDEST_POLICY(4, "DiscardOldestPolicy", new ThreadPoolExecutor.DiscardOldestPolicy()),
/**
* 发生拒绝事件时, 添加新任务并运行最早的任务
*/
- RUNS_OLDEST_TASK_POLICY(5, new RejectedPolicies.RunsOldestTaskPolicy()),
+ RUNS_OLDEST_TASK_POLICY(5, "RunsOldestTaskPolicy", new RejectedPolicies.RunsOldestTaskPolicy()),
/**
* 使用阻塞方法将拒绝任务添加队列, 可保证任务不丢失
*/
- SYNC_PUT_QUEUE_POLICY(6, new RejectedPolicies.SyncPutQueuePolicy());
+ SYNC_PUT_QUEUE_POLICY(6, "SyncPutQueuePolicy", new RejectedPolicies.SyncPutQueuePolicy());
/**
* 类型
*/
public Integer type;
+ /**
+ * 名称
+ */
+ public String name;
+
/**
* 线程池拒绝策略
*/
public RejectedExecutionHandler rejectedHandler;
- RejectedTypeEnum(Integer type, RejectedExecutionHandler rejectedHandler) {
+ RejectedTypeEnum(Integer type, String name, RejectedExecutionHandler rejectedHandler) {
this.type = type;
+ this.name = name;
this.rejectedHandler = rejectedHandler;
}
@@ -67,6 +73,32 @@ public enum RejectedTypeEnum {
DynamicThreadPoolServiceLoader.register(CustomRejectedExecutionHandler.class);
}
+ /**
+ * Create policy.
+ *
+ * @param name
+ * @return
+ */
+ public static RejectedExecutionHandler createPolicy(String name) {
+ RejectedTypeEnum rejectedTypeEnum = Stream.of(RejectedTypeEnum.values())
+ .filter(each -> Objects.equals(each.name, name))
+ .findFirst()
+ .orElse(null);
+
+ if (rejectedTypeEnum != null) {
+ return rejectedTypeEnum.rejectedHandler;
+ }
+
+ Collection customRejectedExecutionHandlers = DynamicThreadPoolServiceLoader
+ .getSingletonServiceInstances(CustomRejectedExecutionHandler.class);
+ Optional customRejected = customRejectedExecutionHandlers.stream()
+ .filter(each -> Objects.equals(name, each.getName()))
+ .map(each -> each.generateRejected())
+ .findFirst();
+
+ return customRejected.orElse(ABORT_POLICY.rejectedHandler);
+ }
+
/**
* Create policy.
*
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java
index 37f665f0..96186138 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java
@@ -17,6 +17,15 @@ public interface CustomBlockingQueue {
*/
Integer getType();
+ /**
+ * Adapt hippo4j core blocking queue.
+ *
+ * @return
+ */
+ default String getName() {
+ return "";
+ }
+
/**
* Get custom blocking queue.
*
diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java
index 1e466781..62e4e42c 100644
--- a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java
@@ -17,6 +17,15 @@ public interface CustomRejectedExecutionHandler {
*/
Integer getType();
+ /**
+ * Adapt hippo4j core rejected execution handler.
+ *
+ * @return
+ */
+ default String getName() {
+ return "";
+ }
+
/**
* Get custom reject policy.
*
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java
similarity index 98%
rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java
rename to hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java
index 126e2783..b5f48631 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java
+++ b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java
@@ -1,4 +1,4 @@
-package cn.hippo4j.starter.toolkit;
+package cn.hippo4j.core.toolkit.inet;
import cn.hippo4j.common.config.ApplicationContextHolder;
import org.springframework.beans.factory.ListableBeanFactory;
diff --git a/hippo4j-example/pom.xml b/hippo4j-example/pom.xml
index 58558dc1..d339916b 100644
--- a/hippo4j-example/pom.xml
+++ b/hippo4j-example/pom.xml
@@ -10,59 +10,17 @@
hippo4j-example
- jar
+ pom
${project.artifactId}
- Demo project for Spring Boot
+ ${project.artifactId}
true
-
-
- org.springframework.boot
- spring-boot-starter
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
- cn.hippo4j
- hippo4j-spring-boot-starter
- ${revision}
-
-
-
- cn.hippo4j
- open-change-tool
-
-
-
-
- ${project.artifactId}
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- repackage
-
-
-
-
-
-
+
+ hippo4j-example-core
+
diff --git a/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java b/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java
deleted file mode 100644
index f5095e48..00000000
--- a/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package cn.hippo4j.example;
-
-import cn.hippo4j.starter.enable.EnableDynamicThreadPool;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-/**
- * Example application.
- *
- * @author chen.ma
- * @date 2022/01/23 21:06
- */
-@SpringBootApplication
-@EnableDynamicThreadPool
-public class ExampleApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(ExampleApplication.class, args);
- }
-
-}
diff --git a/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler b/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler
deleted file mode 100644
index bdca3f76..00000000
--- a/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler
+++ /dev/null
@@ -1 +0,0 @@
-cn.hippo4j.example.handler.ErrorLogRejectedExecutionHandler
\ No newline at end of file
diff --git a/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java b/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java
deleted file mode 100644
index 787cd8fc..00000000
--- a/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.hippo4j.example;
-
-import lombok.extern.slf4j.Slf4j;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-/**
- * Example application.
- *
- * @author chen.ma
- * @date 2022/1/25 21:34
- */
-@Slf4j
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = ExampleApplication.class)
-public class ExampleApplication {
-
- @Test
- public void test() {
- log.info("test success.");
- }
-
-}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java
new file mode 100644
index 00000000..6c2a7843
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java
@@ -0,0 +1,47 @@
+package cn.hippo4j.core.starter.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * Bootstrap properties.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 00:35
+ */
+@Getter
+@Setter
+@ConfigurationProperties(prefix = BootstrapCoreProperties.PREFIX)
+public class BootstrapCoreProperties {
+
+ public static final String PREFIX = "spring.dynamic.thread-pool";
+
+ /**
+ * Enabled banner
+ */
+ private Boolean enableBanner;
+
+ /***
+ * Enabled collect
+ */
+ private Boolean enabledCollect;
+
+ /**
+ * Check state interval
+ */
+ private String checkStateInterval;
+
+ /**
+ * Notify platforms.
+ */
+ private List notifyPlatforms;
+
+ /**
+ * Executors
+ */
+ private List executors;
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java
new file mode 100644
index 00000000..9156c1b2
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java
@@ -0,0 +1,87 @@
+package cn.hippo4j.core.starter.config;
+
+import cn.hippo4j.common.config.ApplicationContextHolder;
+import cn.hippo4j.common.notify.*;
+import cn.hippo4j.common.notify.platform.DingSendMessageHandler;
+import cn.hippo4j.common.notify.platform.LarkSendMessageHandler;
+import cn.hippo4j.common.notify.platform.WeChatSendMessageHandler;
+import cn.hippo4j.core.config.UtilAutoConfiguration;
+import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler;
+import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh;
+import cn.hippo4j.core.starter.notify.CoreNotifyConfigBuilder;
+import cn.hippo4j.core.starter.support.DynamicThreadPoolPostProcessor;
+import lombok.AllArgsConstructor;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+
+/**
+ * Dynamic thread pool auto configuration.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 00:21
+ */
+@Configuration
+@AllArgsConstructor
+@EnableConfigurationProperties(BootstrapCoreProperties.class)
+@ImportAutoConfiguration({UtilAutoConfiguration.class})
+public class DynamicThreadPoolCoreAutoConfiguration {
+
+ private final BootstrapCoreProperties bootstrapCoreProperties;
+
+ @Bean
+ @Order(Ordered.HIGHEST_PRECEDENCE)
+ public ApplicationContextHolder hippo4JApplicationContextHolder() {
+ return new ApplicationContextHolder();
+ }
+
+ @Bean
+ public AlarmControlHandler alarmControlHandler() {
+ return new AlarmControlHandler();
+ }
+
+ @Bean
+ public NotifyConfigBuilder notifyConfigBuilder(AlarmControlHandler alarmControlHandler) {
+ return new CoreNotifyConfigBuilder(alarmControlHandler, bootstrapCoreProperties);
+ }
+
+ @Bean
+ public HippoSendMessageService hippoSendMessageService(NotifyConfigBuilder notifyConfigBuilder,
+ AlarmControlHandler alarmControlHandler) {
+ return new BaseSendMessageServiceImpl(notifyConfigBuilder, alarmControlHandler);
+ }
+
+ @Bean
+ public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(HippoSendMessageService hippoSendMessageService) {
+ return new ThreadPoolNotifyAlarmHandler(hippoSendMessageService);
+ }
+
+ @Bean
+ public SendMessageHandler dingSendMessageHandler() {
+ return new DingSendMessageHandler();
+ }
+
+ @Bean
+ public SendMessageHandler larkSendMessageHandler() {
+ return new LarkSendMessageHandler();
+ }
+
+ @Bean
+ public SendMessageHandler weChatSendMessageHandler() {
+ return new WeChatSendMessageHandler();
+ }
+
+ @Bean
+ public ThreadPoolDynamicRefresh threadPoolDynamicRefresh(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler) {
+ return new ThreadPoolDynamicRefresh(threadPoolNotifyAlarmHandler);
+ }
+
+ @Bean
+ public DynamicThreadPoolPostProcessor dynamicThreadPoolPostProcessor(ApplicationContextHolder hippo4JApplicationContextHolder) {
+ return new DynamicThreadPoolPostProcessor(bootstrapCoreProperties);
+ }
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java
new file mode 100644
index 00000000..d24a9644
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java
@@ -0,0 +1,65 @@
+package cn.hippo4j.core.starter.config;
+
+import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm;
+import lombok.Data;
+
+/**
+ * Executor properties.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 00:40
+ */
+@Data
+public class ExecutorProperties {
+
+ /**
+ * threadPoolId
+ */
+ private String threadPoolId;
+
+ /**
+ * corePoolSize
+ */
+ private Integer corePoolSize;
+
+ /**
+ * maximumPoolSize
+ */
+ private Integer maximumPoolSize;
+
+ /**
+ * queueCapacity
+ */
+ private Integer queueCapacity;
+
+ /**
+ * blockingQueue
+ */
+ private String blockingQueue;
+
+ /**
+ * rejectedHandler
+ */
+ private String rejectedHandler;
+
+ /**
+ * keepAliveTime
+ */
+ private Long keepAliveTime;
+
+ /**
+ * allowCoreThreadTimeOut
+ */
+ private Boolean allowCoreThreadTimeOut;
+
+ /**
+ * threadNamePrefix
+ */
+ private String threadNamePrefix;
+
+ /**
+ * Notify
+ */
+ private ThreadPoolNotifyAlarm notify;
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java
new file mode 100644
index 00000000..5d560fc7
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java
@@ -0,0 +1,29 @@
+package cn.hippo4j.core.starter.config;
+
+import lombok.Data;
+
+/**
+ * Notify platform properties.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 19:29
+ */
+@Data
+public class NotifyPlatformProperties {
+
+ /**
+ * platform
+ */
+ private String platform;
+
+ /**
+ * secretKey
+ */
+ private String secretKey;
+
+ /**
+ * Default configuration
+ */
+ private String receives;
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java
new file mode 100644
index 00000000..0c7bf603
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java
@@ -0,0 +1,89 @@
+package cn.hippo4j.core.starter.notify;
+
+import cn.hippo4j.common.notify.AlarmControlHandler;
+import cn.hippo4j.common.notify.NotifyConfigBuilder;
+import cn.hippo4j.common.notify.NotifyConfigDTO;
+import cn.hippo4j.core.starter.config.BootstrapCoreProperties;
+import cn.hippo4j.core.starter.config.ExecutorProperties;
+import cn.hippo4j.core.starter.config.NotifyPlatformProperties;
+import cn.hutool.core.util.StrUtil;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import lombok.AllArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Core notify config builder.
+ *
+ * @author chen.ma
+ * @date 2022/2/25 00:24
+ */
+@AllArgsConstructor
+public class CoreNotifyConfigBuilder implements NotifyConfigBuilder {
+
+ private final AlarmControlHandler alarmControlHandler;
+
+ private final BootstrapCoreProperties bootstrapCoreProperties;
+
+ @Override
+ public Map> buildNotify() {
+ Map> resultMap = Maps.newHashMap();
+
+ List executors = bootstrapCoreProperties.getExecutors();
+ for (ExecutorProperties executor : executors) {
+ String threadPoolId = executor.getThreadPoolId();
+ String alarmBuildKey = threadPoolId + "+ALARM";
+ List alarmNotifyConfigs = Lists.newArrayList();
+
+ List notifyPlatforms = bootstrapCoreProperties.getNotifyPlatforms();
+ for (NotifyPlatformProperties platformProperties : notifyPlatforms) {
+ NotifyConfigDTO notifyConfig = new NotifyConfigDTO();
+ notifyConfig.setPlatform(platformProperties.getPlatform());
+ notifyConfig.setThreadPoolId(threadPoolId);
+ notifyConfig.setType("ALARM");
+ notifyConfig.setSecretKey(platformProperties.getSecretKey());
+ notifyConfig.setInterval(executor.getNotify().getInterval());
+ Map receives = executor.getNotify().getReceives();
+ String receive = receives.get(platformProperties.getPlatform());
+ if (StrUtil.isBlank(receive)) {
+ receive = platformProperties.getReceives();
+ }
+ notifyConfig.setReceives(receive);
+ alarmNotifyConfigs.add(notifyConfig);
+ }
+
+ resultMap.put(alarmBuildKey, alarmNotifyConfigs);
+
+ String changeBuildKey = threadPoolId + "+CONFIG";
+ List changeNotifyConfigs = Lists.newArrayList();
+
+ for (NotifyPlatformProperties platformProperties : notifyPlatforms) {
+ NotifyConfigDTO notifyConfig = new NotifyConfigDTO();
+ notifyConfig.setPlatform(platformProperties.getPlatform());
+ notifyConfig.setThreadPoolId(threadPoolId);
+ notifyConfig.setType("CONFIG");
+ notifyConfig.setSecretKey(platformProperties.getSecretKey());
+
+ Map receives = executor.getNotify().getReceives();
+ String receive = receives.get(platformProperties.getPlatform());
+ if (StrUtil.isBlank(receive)) {
+ receive = platformProperties.getReceives();
+ }
+ notifyConfig.setReceives(receive);
+ changeNotifyConfigs.add(notifyConfig);
+ }
+
+ resultMap.put(changeBuildKey, changeNotifyConfigs);
+ }
+
+ resultMap.forEach((key, val) ->
+ val.stream().filter(each -> StrUtil.equals("ALARM", each.getType()))
+ .forEach(each -> alarmControlHandler.initCacheAndLock(each.getThreadPoolId(), each.getPlatform(), each.getInterval()))
+ );
+
+ return resultMap;
+ }
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java
new file mode 100644
index 00000000..3fc3d7a3
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java
@@ -0,0 +1,147 @@
+package cn.hippo4j.core.starter.support;
+
+import cn.hippo4j.common.config.ApplicationContextHolder;
+import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm;
+import cn.hippo4j.core.executor.DynamicThreadPool;
+import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
+import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
+import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
+import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
+import cn.hippo4j.core.executor.support.*;
+import cn.hippo4j.core.starter.config.BootstrapCoreProperties;
+import cn.hippo4j.core.starter.config.ExecutorProperties;
+import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.task.TaskDecorator;
+
+import java.util.Objects;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Dynamic threadPool post processor.
+ *
+ * @author chen.ma
+ * @date 2021/8/2 20:40
+ */
+@Slf4j
+@AllArgsConstructor
+public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
+
+ private final BootstrapCoreProperties bootstrapCoreProperties;
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof DynamicThreadPoolExecutor) {
+ DynamicThreadPool dynamicThreadPool;
+ try {
+ dynamicThreadPool = ApplicationContextHolder.findAnnotationOnBean(beanName, DynamicThreadPool.class);
+ if (Objects.isNull(dynamicThreadPool)) {
+ // 适配低版本 SpringBoot
+ dynamicThreadPool = DynamicThreadPoolAnnotationUtil.findAnnotationOnBean(beanName, DynamicThreadPool.class);
+ if (Objects.isNull(dynamicThreadPool)) {
+ return bean;
+ }
+ }
+ } catch (Exception ex) {
+ log.error("Failed to create dynamic thread pool in annotation mode.", ex);
+ return bean;
+ }
+
+ DynamicThreadPoolExecutor dynamicExecutor = (DynamicThreadPoolExecutor) bean;
+ DynamicThreadPoolWrapper wrap = new DynamicThreadPoolWrapper(dynamicExecutor.getThreadPoolId(), dynamicExecutor);
+ ThreadPoolExecutor remoteExecutor = fillPoolAndRegister(wrap);
+ return remoteExecutor;
+ }
+
+ if (bean instanceof DynamicThreadPoolWrapper) {
+ DynamicThreadPoolWrapper wrap = (DynamicThreadPoolWrapper) bean;
+ registerAndSubscribe(wrap);
+ }
+
+ return bean;
+ }
+
+ /**
+ * Register and subscribe.
+ *
+ * @param dynamicThreadPoolWrap
+ */
+ protected void registerAndSubscribe(DynamicThreadPoolWrapper dynamicThreadPoolWrap) {
+ fillPoolAndRegister(dynamicThreadPoolWrap);
+ }
+
+ /**
+ * Fill the thread pool and register.
+ *
+ * @param dynamicThreadPoolWrap
+ */
+ protected ThreadPoolExecutor fillPoolAndRegister(DynamicThreadPoolWrapper dynamicThreadPoolWrap) {
+ String threadPoolId = dynamicThreadPoolWrap.getTpId();
+ ThreadPoolExecutor newDynamicPoolExecutor = dynamicThreadPoolWrap.getExecutor();
+
+ ExecutorProperties executorProperties = bootstrapCoreProperties.getExecutors()
+ .stream()
+ .filter(each -> Objects.equals(threadPoolId, each.getThreadPoolId()))
+ .findFirst()
+ .orElse(null);
+ if (executorProperties != null) {
+ try {
+ // 使用相关参数创建线程池
+ BlockingQueue workQueue = QueueTypeEnum.createBlockingQueue(executorProperties.getBlockingQueue(), executorProperties.getQueueCapacity());
+ newDynamicPoolExecutor = ThreadPoolBuilder.builder()
+ .dynamicPool()
+ .workQueue(workQueue)
+ .threadFactory(threadPoolId)
+ .poolThreadSize(executorProperties.getCorePoolSize(), executorProperties.getMaximumPoolSize())
+ .keepAliveTime(executorProperties.getKeepAliveTime(), TimeUnit.SECONDS)
+ .rejected(RejectedTypeEnum.createPolicy(executorProperties.getRejectedHandler()))
+ .allowCoreThreadTimeOut(executorProperties.getAllowCoreThreadTimeOut())
+ .build();
+
+ // 设置动态线程池增强参数
+ ThreadPoolNotifyAlarm notify = executorProperties.getNotify();
+ if (dynamicThreadPoolWrap.getExecutor() instanceof AbstractDynamicExecutorSupport) {
+ ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm(
+ notify.getIsAlarm(),
+ notify.getCapacityAlarm(),
+ notify.getActiveAlarm()
+ );
+
+ threadPoolNotifyAlarm.setInterval(notify.getInterval());
+ threadPoolNotifyAlarm.setReceives(notify.getReceives());
+ GlobalNotifyAlarmManage.put(threadPoolId, threadPoolNotifyAlarm);
+
+ TaskDecorator taskDecorator = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).getTaskDecorator();
+ ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setTaskDecorator(taskDecorator);
+
+ long awaitTerminationMillis = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).awaitTerminationMillis;
+ boolean waitForTasksToCompleteOnShutdown = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).waitForTasksToCompleteOnShutdown;
+ ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setSupportParam(awaitTerminationMillis, waitForTasksToCompleteOnShutdown);
+ }
+
+ dynamicThreadPoolWrap.setExecutor(newDynamicPoolExecutor);
+ } catch (Exception ex) {
+ log.error("Failed to initialize thread pool configuration. error message :: {}", ex.getMessage());
+ } finally {
+ if (Objects.isNull(dynamicThreadPoolWrap.getExecutor())) {
+ dynamicThreadPoolWrap.setExecutor(CommonDynamicThreadPool.getInstance(threadPoolId));
+ }
+ }
+
+ GlobalThreadPoolManage.registerPool(dynamicThreadPoolWrap.getTpId(), dynamicThreadPoolWrap);
+ }
+
+ return newDynamicPoolExecutor;
+ }
+
+}
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE
new file mode 100644
index 00000000..ff773796
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://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.
diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..6b409eb7
--- /dev/null
+++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hippo4j.core.starter.config.DynamicThreadPoolCoreAutoConfiguration
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java
index 0ca29d8e..76cb7c16 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java
@@ -1,5 +1,6 @@
package cn.hippo4j.starter.config;
+import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@@ -15,7 +16,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@Getter
@Setter
@ConfigurationProperties(prefix = BootstrapProperties.PREFIX)
-public class BootstrapProperties {
+public class BootstrapProperties implements BootstrapPropertiesInterface {
public static final String PREFIX = "spring.dynamic.thread-pool";
@@ -52,7 +53,7 @@ public class BootstrapProperties {
/**
* Print dynamic thread pool banner
*/
- private Boolean banner = true;
+ private Boolean enableBanner = true;
/**
* Enable client data collect
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java
index 215a2e7d..7ff48524 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java
@@ -2,6 +2,7 @@ package cn.hippo4j.starter.config;
import cn.hippo4j.common.api.ThreadDetailState;
import cn.hippo4j.common.config.ApplicationContextHolder;
+import cn.hippo4j.core.config.UtilAutoConfiguration;
import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh;
import cn.hippo4j.core.toolkit.IdentifyUtil;
import cn.hippo4j.core.toolkit.inet.InetUtils;
@@ -11,7 +12,7 @@ import cn.hippo4j.starter.core.ConfigService;
import cn.hippo4j.starter.core.DynamicThreadPoolPostProcessor;
import cn.hippo4j.starter.core.ThreadPoolConfigService;
import cn.hippo4j.starter.core.ThreadPoolOperation;
-import cn.hippo4j.starter.enable.MarkerConfiguration;
+import cn.hippo4j.core.enable.MarkerConfiguration;
import cn.hippo4j.starter.event.ApplicationContentPostProcessor;
import cn.hippo4j.starter.handler.BaseThreadDetailStateHandler;
import cn.hippo4j.starter.handler.DynamicThreadPoolBannerHandler;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java
index 9349b267..55b9c47b 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java
@@ -1,5 +1,6 @@
package cn.hippo4j.starter.core;
+import cn.hippo4j.core.config.ConfigEmptyException;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java
index 09fc30e9..bd7dca8c 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java
@@ -7,6 +7,7 @@ import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.web.base.Result;
+import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
@@ -15,7 +16,7 @@ import cn.hippo4j.core.executor.support.*;
import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh;
import cn.hippo4j.starter.config.BootstrapProperties;
import cn.hippo4j.starter.remote.HttpAgent;
-import cn.hippo4j.starter.toolkit.DynamicThreadPoolAnnotationUtil;
+import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil;
import cn.hutool.core.util.BooleanUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java
index 43baf497..818ff602 100644
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java
+++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java
@@ -42,7 +42,7 @@ public class DynamicThreadPoolBannerHandler implements InitializingBean {
"|___/ \\_, |_||_\\__,_|_|_|_|_\\__| |_| |_| \n" +
" |__/ \n";
- if (properties.getBanner()) {
+ if (properties.getEnableBanner()) {
String version = getVersion();
version = (version != null) ? " (v" + version + ")" : "no version.";
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json
deleted file mode 100644
index 23af7381..00000000
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json
+++ /dev/null
@@ -1,185 +0,0 @@
-{
- "msg_type": "interactive",
- "card": {
- "config": {
- "wide_screen_mode": true
- },
- "header": {
- "template": "red",
- "title": {
- "content": "[🔥警报] %s 动态线程池运行告警",
- "tag": "plain_text"
- }
- },
- "elements": [
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 线程池ID:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 应用名称:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 应用实例:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 报警类型:** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 核心线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 最大线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 当前线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 活跃线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 最大任务数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 线程池任务总量:** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 队列类型:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 队列容量:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 队列元素个数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 队列剩余个数:** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 拒绝策略:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 拒绝策略执行次数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** OWNER:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 播报时间: ** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "tag": "note",
- "elements": [
- {
- "tag": "plain_text",
- "content": "提示: %s 分钟内此线程池不会重复告警(可配置)"
- }
- ]
- }
- ]
- }
-}
-
diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json
deleted file mode 100644
index 9d85622e..00000000
--- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json
+++ /dev/null
@@ -1,150 +0,0 @@
-{
- "msg_type": "interactive",
- "card": {
-
- "config": {
- "wide_screen_mode": true
- },
- "header": {
- "template": "greed",
- "title": {
- "content": "[通知] %s 动态线程池参数变更",
- "tag": "plain_text"
- }
- },
- "elements": [
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 线程池ID:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 应用名称:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 应用实例:** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 核心线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 最大线程数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 核心线程超时:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 线程存活时间:** %s / SECONDS",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** 队列类型:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 队列容量:** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "fields": [
- {
- "is_short": true,
- "text": {
- "content": "** AGO 拒绝策略:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** NOW 拒绝策略执行次数:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** OWNER:** %s",
- "tag": "lark_md"
- }
- },
- {
- "is_short": true,
- "text": {
- "content": "** 播报时间: ** %s",
- "tag": "lark_md"
- }
- }
- ],
- "tag": "div"
- },
- {
- "tag": "hr"
- },
- {
- "tag": "note",
- "elements": [
- {
- "tag": "plain_text",
- "content": "提示:动态线程池配置变更实时通知(无限制)"
- }
- ]
- }
- ]
- }
-}