diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
index 5963fa69..00dbea90 100644
--- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
+++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
@@ -8,7 +8,9 @@ package org.dromara.sms4j.comm.constant;
* 2023/3/31 19:33
**/
public abstract class Constant {
- /** 项目版本号*/
+ /**
+ * 项目版本号
+ */
public static final String VERSION = "V 3.0.1";
/**
@@ -37,7 +39,9 @@ public abstract class Constant {
*/
public static final String HUAWEI_JAVA_DATE = "yyyy-MM-dd'T'HH:mm:ss'Z'";
- /** 云片短信国内短信请求地址*/
+ /**
+ * 云片短信国内短信请求地址
+ */
public static final String YUNPIAN_URL = "https://sms.yunpian.com/v2";
/**
@@ -50,6 +54,11 @@ public abstract class Constant {
*/
public static final String SUPPLIER_KEY = "supplier";
+ /**
+ * 自定义实现工厂路径
+ */
+ public static final String FACTORY_PATH = "factory";
+
private Constant() {
}
}
diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunApplication.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunApplication.java
new file mode 100644
index 00000000..b49f75a7
--- /dev/null
+++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunApplication.java
@@ -0,0 +1,20 @@
+package org.dromara.sms4j.example.zhangjun;
+
+import org.dromara.sms4j.core.factory.SmsFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 自定义广州掌骏短信实现
+ *
+ * @author 4n
+ */
+@SpringBootApplication
+public class ZhangJunApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ZhangJunApplication.class, args);
+ SmsFactory.getBySupplier("zhangjun").sendMessage("17679318598", "154468");
+ }
+
+}
diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunConfig.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunConfig.java
new file mode 100644
index 00000000..18106009
--- /dev/null
+++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunConfig.java
@@ -0,0 +1,23 @@
+package org.dromara.sms4j.example.zhangjun;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.sms4j.comm.constant.SupplierConstant;
+import org.dromara.sms4j.provider.config.BaseConfig;
+
+/**
+ * @author 4n
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ZhangJunConfig extends BaseConfig {
+ private String appId;
+ private String sid;
+ private String url;
+
+ @Override
+ public String getSupplier() {
+ return "zhangjun";
+ }
+
+}
diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunFactory.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunFactory.java
new file mode 100644
index 00000000..51c5ef13
--- /dev/null
+++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunFactory.java
@@ -0,0 +1,27 @@
+package org.dromara.sms4j.example.zhangjun;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
+
+/**
+ *
+ *
掌骏短信
+ *
+ * @author :4n
+ * 2023/10/31 14:54
+ **/
+@NoArgsConstructor
+public class ZhangJunFactory extends AbstractProviderFactory {
+
+ @Override
+ public ZhangJunSmsImpl createSms(ZhangJunConfig ZhangJunConfig) {
+ return new ZhangJunSmsImpl(ZhangJunConfig);
+ }
+
+ @Override
+ public String getSupplier() {
+ return "zhangjun";
+ }
+
+}
diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java
new file mode 100644
index 00000000..f65eaff9
--- /dev/null
+++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java
@@ -0,0 +1,111 @@
+package org.dromara.sms4j.example.zhangjun;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.entity.SmsResponse;
+import org.dromara.sms4j.comm.delayedTime.DelayedTime;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtils;
+import org.dromara.sms4j.provider.service.AbstractSmsBlend;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * @author :4n
+ **/
+@Slf4j
+public class ZhangJunSmsImpl extends AbstractSmsBlend {
+
+ private int retry = 0;
+
+ /**
+ * ZhangJunSmsImpl
+ * 构造器,用于构造短信实现模块
+ *
+ * @author :Wind
+ */
+ public ZhangJunSmsImpl(ZhangJunConfig config, Executor pool, DelayedTime delayedTime) {
+ super(config, pool, delayedTime);
+ }
+
+ /**
+ * ZhangJunSmsImpl
+ *
构造器,用于构造短信实现模块
+ */
+ public ZhangJunSmsImpl(ZhangJunConfig config) {
+ super(config);
+ }
+
+ @Override
+ public String getSupplier() {
+ return "zhangjun";
+ }
+ private LinkedHashMap buildBody(String phone, String message){
+ LinkedHashMap map = new LinkedHashMap<>();
+ map.put("appId", getConfig().getAppId());
+ map.put("sid", getConfig().getSid());
+ map.put("templateId", getConfig().getTemplateId());
+ map.put("phone", phone);
+ Map data = new HashMap<>();
+ data.put("code", message);
+ map.put("data", JSONUtil.toJsonStr(data));
+ return map;
+ }
+ @Override
+ public SmsResponse sendMessage(String phone, String message) {
+ return sendMessage(phone, getConfig().getTemplateId(), buildBody(phone,message));
+ }
+
+ @Override
+ public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) {
+ String messageStr = JSONUtil.toJsonStr(messages);
+ return getSmsResponse(phone, messageStr, templateId);
+ }
+
+ @Override
+ public SmsResponse massTexting(List phones, String message) {
+ LinkedHashMap map = new LinkedHashMap<>();
+// map.put(getConfig().getTemplateName(), message);
+ return massTexting(phones, getConfig().getTemplateId(), map);
+ }
+
+ @Override
+ public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) {
+ String messageStr = JSONUtil.toJsonStr(messages);
+ return getSmsResponse(SmsUtils.arrayToString(phones), messageStr, templateId);
+ }
+
+ private SmsResponse getSmsResponse(String phone, String message, String templateId) {
+ try {
+ SmsResponse smsResponse = getResponse(http.postJson(getConfig().getUrl(), null, message));
+ if(smsResponse.isSuccess() || retry == getConfig().getMaxRetries()){
+ retry = 0;
+ return smsResponse;
+ }
+ return requestRetry(phone, message, templateId);
+ }catch (SmsBlendException e){
+ return requestRetry(phone, message, templateId);
+ }
+ }
+
+ private SmsResponse requestRetry(String phone, String message, String templateId) {
+ http.safeSleep(getConfig().getRetryInterval());
+ retry++;
+ log.warn("短信第 {" + retry + "} 次重新发送");
+ return getSmsResponse(phone, message, templateId);
+ }
+
+ private SmsResponse getResponse(JSONObject resJson) {
+ SmsResponse smsResponse = new SmsResponse();
+ smsResponse.setSuccess("OK".equals(resJson.getStr("Code")));
+ smsResponse.setData(resJson);
+ smsResponse.setConfigId(getConfigId());
+ return smsResponse;
+ }
+
+}
\ No newline at end of file
diff --git a/sms4j-spring-boot-example/src/main/resources/application.yml b/sms4j-spring-boot-example/src/main/resources/application.yml
index fc1c106e..b9aecd22 100644
--- a/sms4j-spring-boot-example/src/main/resources/application.yml
+++ b/sms4j-spring-boot-example/src/main/resources/application.yml
@@ -73,4 +73,12 @@ sms:
base-url: https://app.cloopen.com:8883/2013-12-26
access-key-id: 你的Access Key
access-key-secret: 你的Access Key Secret
- sdkAppId: 你的应用ID
\ No newline at end of file
+ sdkAppId: 你的应用ID
+ #自定义广州掌骏短信,添加factory全路径。config,factory,SmsImpl复制其他默认实现即可,修改对应的supplier和发送核心逻辑即可
+ zhangjun:
+ supplier: zhangjun
+ factory: org.dromara.sms4j.example.zhangjun.ZhangJunFactory
+ templateId: d2a****777
+ appId: 64c52d2a****77775fe72e3
+ sid: d2a****777
+ url: https://sms.idowe.com/**/**/**/send
\ No newline at end of file
diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java
index a6a05886..567778d8 100644
--- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java
+++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java
@@ -1,12 +1,18 @@
package org.dromara.sms4j.starter.config;
+import cn.hutool.core.util.ObjectUtil;
+import lombok.SneakyThrows;
import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.comm.constant.Constant;
+import org.dromara.sms4j.comm.enumerate.ConfigType;
import org.dromara.sms4j.provider.config.SmsConfig;
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
+import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -23,6 +29,26 @@ public class SupplierConfig {
return new LinkedHashMap<>();
}
+ @Bean
+ @ConditionalOnBean({SmsConfig.class})
+ @SneakyThrows
+ protected List> factoryList(Map> blends, SmsConfig smsConfig) {
+ //注入自定义实现工厂
+ List> factoryList = new ArrayList<>();
+ if (ConfigType.YAML.equals(smsConfig.getConfigType())) {
+ for (String configId : blends.keySet()) {
+ Map configMap = blends.get(configId);
+ Object factoryPath = configMap.get(Constant.FACTORY_PATH);
+ if (ObjectUtil.isNotEmpty(factoryPath)) {
+ //反射创建实例
+ Class> newClass = (Class>) Class.forName(factoryPath.toString());
+ BaseProviderFactory extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig> factory = newClass.newInstance();
+ factoryList.add(factory);
+ }
+ }
+ }
+ return factoryList;
+ }
@Bean
protected SmsBlendsInitializer smsBlendsInitializer(List> factoryList,