参考资料
- 代码优雅之道——如何干掉过多的if else
目录
- 一. 前期准备
- 1.1 标记邮箱种类的接口
- 1.2 邮箱类型区分类
- 1.3 入参Form实体类
- 二. 邮件发送的业务聚合类
- 三. 定义函数式接口,创建邮件发送的Map
- 四. 效果
一. 前期准备
1.1 标记邮箱种类的接口
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MailCategoryAnnotation {
String mailCode();
}
1.2 邮箱类型区分类
- 考虑到之后可能会有其他类型的区分,因此使用了
内部class
public final class CategoryKbn {
// 邮件种类
public final class MailCategory {
public final static String Mail_163 = "1";
public final static String Mail_QQ = "2";
public final static String Mail_G = "3";
public final static String Mail_OutLook = "4";
}
// 其他种类。。。
}
1.3 入参Form实体类
import lombok.Data;
@Data
public class Test27Form {
// 用于标记邮箱的种类
private String category;
}
二. 邮件发送的业务聚合类
- 自定义的注解作用在Method上,用来标记邮件发送方法的类型
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class SendMailService {
@MailCategoryAnnotation(mailCode = CategoryKbn.MailCategory.Mail_QQ)
public void sendQQMail(Map<String, String> mailInfoMap) {
System.out.println("QQ邮箱发送邮件。。。");
System.out.println(mailInfoMap);
}
@MailCategoryAnnotation(mailCode = CategoryKbn.MailCategory.Mail_163)
public void send163Mail(Map<String, String> mailInfoMap) {
System.out.println("163邮箱发送邮件。。。");
System.out.println(mailInfoMap);
}
@MailCategoryAnnotation(mailCode = CategoryKbn.MailCategory.Mail_G)
public void sendGMail(Map<String, String> mailInfoMap) {
System.out.println("GMail邮箱发送邮件。。。");
System.out.println(mailInfoMap);
}
@MailCategoryAnnotation(mailCode = CategoryKbn.MailCategory.Mail_OutLook)
public void sendOutLookMail(Map<String, String> mailInfoMap) {
System.out.println("OutLook邮箱发送邮件。。。");
System.out.println(mailInfoMap);
}
}
三. 定义函数式接口,创建邮件发送的Map
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Service
public class Test27Service implements InitializingBean {
@Autowired
private SendMailService mailService;
/*
邮件种类code和发送邮件方法的映射Map
*/
private final Map<String, MailFunction<Map<String, String>>> strategySendMailMap = new HashMap<>();
// 标记此接口为函数式编程接口
@FunctionalInterface
interface MailFunction<T> {
// 不知道参数会是什么类型,就使用了泛型
void sendMail(T mailInfo) throws Exception;
}
@Override
public void afterPropertiesSet() throws Exception {
for (Method mailSendMethod : Arrays.asList(mailService.getClass().getMethods())) {
// 如果该方法上没有被标记MailCategoryAnnotation自定义注解就跳过
if (!mailSendMethod.isAnnotationPresent(MailCategoryAnnotation.class)) {
continue;
}
// 获取Method上被标记的MailCategoryAnnotation注解上的mailCode
String mailCode = mailSendMethod.getAnnotation(MailCategoryAnnotation.class).mailCode();
// 将mailcode和发送邮件的方法添加到Map中
strategySendMailMap.put(mailCode, (T) -> mailSendMethod.invoke(mailService, T));
}
}
public void execute(String category) throws Exception {
// 发送邮件时所需要的参数
Map<String, String> mailInfoMap = new HashMap<>() {
{
put("id", "110120");
put("name", "jiafeitian");
}
};
// 根据category获取邮件的发送方法,并执行
MailFunction<Map<String, String>> sendMailFunction = strategySendMailMap.get(category);
sendMailFunction.sendMail(mailInfoMap);
}
}
四. 效果
⏹前台
const jsonData = {
category: '2'
};
$.ajax({
url: "/test27/test1",
type: 'POST',
data: JSON.stringify(jsonData),
contentType: 'application/json;charset=utf-8',
success: function (data, status, xhr) {
console.log(data);
}
});
⏹后台
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
@PostMapping("/test1")
public ResponseEntity<Void> test1(@RequestBody Test27Form form) throws Exception {
service.execute(form.getCategory());
return ResponseEntity.noContent().build();
}
👇效果