# Notify 系统通知
MornBoot提供通用的注解,用于声明系统通知,并提供灵活的分发、处理机制。适用于:
- 消息提醒(短信、邮件等)
- 消息推送(Web推送、手机推送等)
- 告警推送
- 第三方系统通知
Since:v1.2.1
# 必要配置
SpringBootApplication
@EnableNotify // 开启通知
# Notify Annotation
使用@Notify
注解声明通知的类型、名称,使用@NotifyReceiver
注解声明接收人的类型、唯一标识。
@Slf4j
@Component
public class TestNotifyBean {
/**
* 向角色发送邮箱验证码
*/
@Notify(type = "email", name = "captcha")
@NotifyReceiver(type = "role", value = {"r1", "r2"})
public void captchaToRole() {
log.info("Do some thing and Notify to role.");
}
}
# Notify Processor
实现NotifyProcessor
接口,以处理系统通知。使用@NotifyType
标识可处理的通知类型。MornBoot
会自动将NotifyMeta
分发给符合规则的NotifyProcessor
。
@NotifyType
默认为*
代表可处理所有类型的系统通知。
@Slf4j
@NotifyType("email")
public class EmailNotifyProcessor implements NotifyProcessor {
@Override
public void handle(NotifyMeta meta) {
log.info("Notify|{}", meta);
}
}
系统通知的处理会在方法执行完毕后触发。captchaToRole
的日志:
Do some thing and Notify to role.
Notify|NotifyMeta(source=null, notifyType=email, notifyName=captcha, receiverType=role, receiverValues=[r1, r2])
# Notify Arguments
使用NotifyArgs
可以动态指定接收人。
由于
NotifyArguments
基于线程变量ThreadLocal
实现。 在一个线程中,触发多次Notify
时,需要使用NotifyArguments.getNotifyArgs(String notifyType, String notifyName)
指明所属Notify
。
@Slf4j
@Component
public class TestNotifyBean {
/**
* 向角色发送邮箱验证码
*/
@Notify(type = "email", name = "captcha")
@NotifyReceiver(type = "role" /*, value = {"r1", "r2"}*/)
public void captchaToRole() {
log.info("Do some thing and Notify to role.");
// 设置通知参数
NotifyArgs notifyArgs = NotifyArguments.getNotifyArgs();
notifyArgs.addReceiverValue("r1");
notifyArgs.addReceiverValue("r2");
}
}
# Template
通知内容通常比较固定,可以使用内容模板进行管理。
SpringBootApplication启动类配置
@EnableTemplate // 开启模板渲染
国际化资源文件:
tpl.email.captcha=尊敬的${role}您好,您的验证码是${captcha}。
使用@Template
标注模板类型,与@Notify
配合使用时,MornBoot
会根据通知类型和名称自动填充模板名称@Template#name
。
- 默认的填充规则为
tpl.[notifyType].[notifyName]
。 - 配置
morn.template.prefix
属性可以修改前缀。 - 使用
NotifyArguments
指定模板变量。 resource
表示使用国际化资源文件管理模板内容。
@Slf4j
@Component
public class TestNotifyBean {
/**
* 向角色发送邮箱验证码
*/
@Template(RESOURCE)
@Notify(type = "email", name = "captcha")
@NotifyReceiver(type = "role", value = {"r1", "r2"})
public void captchaToRole() {
// 设置模板参数
CriteriaMap templateArgs = NotifyArguments.getTemplateArgs();
templateArgs.put("role", "管理员");
templateArgs.put("captcha", "a1b2c3");
}
}
实现TemplateNotifyProcessor<T>
处理模板系统通知。MornBoot
会将模板变量填充进模板内容。
@Slf4j
@NotifyType
public class EmailNotifyProcessor extends AbstractTemplateNotifyProcessor<String> {
@Override
public void handle(NotifyMeta meta) {
log.info("Content:{}", meta, getTemplateContent());
}
}
captchaToRole
的日志:
尊敬的管理员您好,您的验证码是a1b2c3。
实现新的模板解析器TemplateResolver
,并指定新的@TemplateType
,可以自定义模板。参考源码:
@TemplateType(RESOURCE)
public class ResourceTemplateResolver extends AbstractTemplateResolver<String> {
/**
* 国际化翻译器
*/
private final Translator translator;
public ResourceTemplateResolver(TemplateProperties templateProperties, Translator translator) {
super(templateProperties);
this.translator = translator;
}
@Override
public String resolve() {
String templatePath = getTemplatePath();
String templateContent = translator.translate(templatePath);
CriteriaMap args = getTemplateMeta().getArgs();
for (Entry<String, Object> entry : args.entrySet()) {
String name = entry.getKey();
String value = String.valueOf(entry.getValue());
templateContent = StringUtils.replace(templateContent, getPlaceholder(name), value);
}
return templateContent;
}
/**
* 生成占位符
*
* @param name 属性名称
* @return 占位符
*/
private String getPlaceholder(String name) {
return String.format("${%s}", name);
}
}
# 其它用法
使用NotifyDispatcher
可以直接分发系统通知,而不需要通过注解驱动。
public class NotifyTrigger {
private final NotifyDispatcher notifyDispatcher;
public NotifyAspect(NotifyDispatcher notifyDispatcher) {
this.notifyDispatcher = notifyDispatcher;
}
public void triggering() {
NotifyMeta notifyMeta = new NotifyMeta();
notifyDispatcher.handle(notifyMeta);
}
}