缓存改造:MailTemplate、MailAccount 使用 Redis 作为缓存
This commit is contained in:
parent
d23d72c8bb
commit
5dda7a3c05
|
@ -74,4 +74,19 @@ public interface RedisKeyConstants {
|
|||
*/
|
||||
String NOTIFY_TEMPLATE = "notify_template";
|
||||
|
||||
/**
|
||||
* 邮件账号的缓存
|
||||
*
|
||||
* KEY 格式:sms_template::{id}
|
||||
* VALUE 数据格式:String 账号信息
|
||||
*/
|
||||
String MAIL_ACCOUNT = "mail_account";
|
||||
|
||||
/**
|
||||
* 邮件模版的缓存
|
||||
*
|
||||
* KEY 格式:mail_template::{code}
|
||||
* VALUE 数据格式:String 模版信息
|
||||
*/
|
||||
String MAIL_TEMPLATE = "mail_template";
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.consumer.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailAccountRefreshMessage;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailTemplateRefreshMessage;
|
||||
import cn.iocoder.yudao.module.system.service.mail.MailAccountService;
|
||||
import cn.iocoder.yudao.module.system.service.mail.MailTemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link MailAccountRefreshMessage} 的消费者
|
||||
*
|
||||
* @author wangjingyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MailAccountRefreshConsumer extends AbstractChannelMessageListener<MailAccountRefreshMessage> {
|
||||
|
||||
@Resource
|
||||
private MailAccountService mailAccountService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MailAccountRefreshMessage message) {
|
||||
log.info("[onMessage][收到 Mail Account 刷新信息]");
|
||||
mailAccountService.initLocalCache();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.consumer.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailTemplateRefreshMessage;
|
||||
import cn.iocoder.yudao.module.system.service.mail.MailTemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link MailTemplateRefreshMessage} 的消费者
|
||||
*
|
||||
* @author wangjingyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MailTemplateRefreshConsumer extends AbstractChannelMessageListener<MailTemplateRefreshMessage> {
|
||||
|
||||
@Resource
|
||||
private MailTemplateService mailTemplateService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MailTemplateRefreshMessage message) {
|
||||
log.info("[onMessage][收到 Mail Template 刷新信息]");
|
||||
mailTemplateService.initLocalCache();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.message.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 邮箱账号的数据刷新 Message
|
||||
*
|
||||
* @author wangjingyi
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MailAccountRefreshMessage extends AbstractChannelMessage {
|
||||
|
||||
@Override
|
||||
public String getChannel() {
|
||||
return "system.mail-account.refresh";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.message.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 邮箱模板的数据刷新 Message
|
||||
*
|
||||
* @author wangjingyi
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MailTemplateRefreshMessage extends AbstractChannelMessage {
|
||||
|
||||
@Override
|
||||
public String getChannel() {
|
||||
return "system.mail-template.refresh";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
package cn.iocoder.yudao.module.system.mq.producer.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailAccountRefreshMessage;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailTemplateRefreshMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -22,22 +20,6 @@ public class MailProducer {
|
|||
@Resource
|
||||
private RedisMQTemplate redisMQTemplate;
|
||||
|
||||
/**
|
||||
* 发送 {@link MailTemplateRefreshMessage} 消息
|
||||
*/
|
||||
public void sendMailTemplateRefreshMessage() {
|
||||
MailTemplateRefreshMessage message = new MailTemplateRefreshMessage();
|
||||
redisMQTemplate.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 {@link MailAccountRefreshMessage} 消息
|
||||
*/
|
||||
public void sendMailAccountRefreshMessage() {
|
||||
MailAccountRefreshMessage message = new MailAccountRefreshMessage();
|
||||
redisMQTemplate.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 {@link MailSendMessage} 消息
|
||||
*
|
||||
|
|
|
@ -17,19 +17,6 @@ import java.util.List;
|
|||
*/
|
||||
public interface MailAccountService {
|
||||
|
||||
/**
|
||||
* 初始化邮箱账号的本地缓存
|
||||
*/
|
||||
void initLocalCache();
|
||||
|
||||
/**
|
||||
* 从缓存中获取邮箱账号
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 邮箱账号
|
||||
*/
|
||||
MailAccountDO getMailAccountFromCache(Long id);
|
||||
|
||||
/**
|
||||
* 创建邮箱账号
|
||||
*
|
||||
|
@ -60,6 +47,14 @@ public interface MailAccountService {
|
|||
*/
|
||||
MailAccountDO getMailAccount(Long id);
|
||||
|
||||
/**
|
||||
* 从缓存中获取邮箱账号
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 邮箱账号
|
||||
*/
|
||||
MailAccountDO getMailAccountFromCache(Long id);
|
||||
|
||||
/**
|
||||
* 获取邮箱账号分页信息
|
||||
*
|
||||
|
|
|
@ -7,20 +7,18 @@ import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccou
|
|||
import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
|
||||
import lombok.Getter;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS;
|
||||
|
||||
/**
|
||||
* 邮箱账号 Service 实现类
|
||||
|
@ -39,46 +37,16 @@ public class MailAccountServiceImpl implements MailAccountService {
|
|||
@Resource
|
||||
private MailTemplateService mailTemplateService;
|
||||
|
||||
@Resource
|
||||
private MailProducer mailProducer;
|
||||
|
||||
/**
|
||||
* 邮箱账号缓存
|
||||
* key:邮箱账号编码 {@link MailAccountDO#getId()}
|
||||
*
|
||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||
*/
|
||||
@Getter
|
||||
private volatile Map<Long, MailAccountDO> mailAccountCache;
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void initLocalCache() {
|
||||
// 第一步:查询数据
|
||||
List<MailAccountDO> accounts = mailAccountMapper.selectList();
|
||||
log.info("[initLocalCache][缓存邮箱账号,数量:{}]", accounts.size());
|
||||
|
||||
// 第二步:构建缓存
|
||||
mailAccountCache = convertMap(accounts, MailAccountDO::getId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailAccountDO getMailAccountFromCache(Long id) {
|
||||
return mailAccountCache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createMailAccount(MailAccountCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
MailAccountDO account = MailAccountConvert.INSTANCE.convert(createReqVO);
|
||||
mailAccountMapper.insert(account);
|
||||
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailAccountRefreshMessage();
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#updateReqVO.id")
|
||||
public void updateMailAccount(MailAccountUpdateReqVO updateReqVO) {
|
||||
// 校验是否存在
|
||||
validateMailAccountExists(updateReqVO.getId());
|
||||
|
@ -86,11 +54,10 @@ public class MailAccountServiceImpl implements MailAccountService {
|
|||
// 更新
|
||||
MailAccountDO updateObj = MailAccountConvert.INSTANCE.convert(updateReqVO);
|
||||
mailAccountMapper.updateById(updateObj);
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailAccountRefreshMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#id")
|
||||
public void deleteMailAccount(Long id) {
|
||||
// 校验是否存在账号
|
||||
validateMailAccountExists(id);
|
||||
|
@ -101,8 +68,6 @@ public class MailAccountServiceImpl implements MailAccountService {
|
|||
|
||||
// 删除
|
||||
mailAccountMapper.deleteById(id);
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailAccountRefreshMessage();
|
||||
}
|
||||
|
||||
private void validateMailAccountExists(Long id) {
|
||||
|
@ -116,6 +81,12 @@ public class MailAccountServiceImpl implements MailAccountService {
|
|||
return mailAccountMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#id", unless = "#result == null")
|
||||
public MailAccountDO getMailAccountFromCache(Long id) {
|
||||
return getMailAccount(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MailAccountDO> getMailAccountPage(MailAccountPageReqVO pageReqVO) {
|
||||
return mailAccountMapper.selectPage(pageReqVO);
|
||||
|
|
|
@ -18,11 +18,6 @@ import java.util.Map;
|
|||
*/
|
||||
public interface MailTemplateService {
|
||||
|
||||
/**
|
||||
* 初始化邮件模版的本地缓存
|
||||
*/
|
||||
void initLocalCache();
|
||||
|
||||
/**
|
||||
* 邮件模版创建
|
||||
*
|
||||
|
|
|
@ -10,14 +10,14 @@ import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemp
|
|||
import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
@ -25,8 +25,8 @@ import java.util.Map;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_CODE_EXISTS;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 邮箱模版 Service 实现类
|
||||
|
@ -47,29 +47,6 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
@Resource
|
||||
private MailTemplateMapper mailTemplateMapper;
|
||||
|
||||
@Resource
|
||||
private MailProducer mailProducer;
|
||||
|
||||
/**
|
||||
* 邮件模板缓存
|
||||
* key:邮件模版标识 {@link MailTemplateDO#getCode()}
|
||||
*
|
||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||
*/
|
||||
@Getter
|
||||
private volatile Map<String, MailTemplateDO> mailTemplateCache;
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void initLocalCache() {
|
||||
// 第一步:查询数据
|
||||
List<MailTemplateDO> templates = mailTemplateMapper.selectList();
|
||||
log.info("[initLocalCache][缓存邮件模版,数量:{}]", templates.size());
|
||||
|
||||
// 第二步:构建缓存
|
||||
mailTemplateCache = convertMap(templates, MailTemplateDO::getCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createMailTemplate(MailTemplateCreateReqVO createReqVO) {
|
||||
// 校验 code 是否唯一
|
||||
|
@ -79,12 +56,12 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
MailTemplateDO template = MailTemplateConvert.INSTANCE.convert(createReqVO)
|
||||
.setParams(parseTemplateContentParams(createReqVO.getContent()));
|
||||
mailTemplateMapper.insert(template);
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailTemplateRefreshMessage();
|
||||
return template.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.NOTIFY_TEMPLATE,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为可能修改到 code 字段,不好清理
|
||||
public void updateMailTemplate(@Valid MailTemplateUpdateReqVO updateReqVO) {
|
||||
// 校验是否存在
|
||||
validateMailTemplateExists(updateReqVO.getId());
|
||||
|
@ -95,12 +72,10 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
MailTemplateDO updateObj = MailTemplateConvert.INSTANCE.convert(updateReqVO)
|
||||
.setParams(parseTemplateContentParams(updateReqVO.getContent()));
|
||||
mailTemplateMapper.updateById(updateObj);
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailTemplateRefreshMessage();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void validateCodeUnique(Long id, String code) {
|
||||
void validateCodeUnique(Long id, String code) {
|
||||
MailTemplateDO template = mailTemplateMapper.selectByCode(code);
|
||||
if (template == null) {
|
||||
return;
|
||||
|
@ -113,14 +88,14 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.NOTIFY_TEMPLATE,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 id 不是直接的缓存 code,不好清理
|
||||
public void deleteMailTemplate(Long id) {
|
||||
// 校验是否存在
|
||||
validateMailTemplateExists(id);
|
||||
|
||||
// 删除
|
||||
mailTemplateMapper.deleteById(id);
|
||||
// 发送刷新消息
|
||||
mailProducer.sendMailTemplateRefreshMessage();
|
||||
}
|
||||
|
||||
private void validateMailTemplateExists(Long id) {
|
||||
|
@ -132,6 +107,12 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
@Override
|
||||
public MailTemplateDO getMailTemplate(Long id) {return mailTemplateMapper.selectById(id);}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_TEMPLATE, key = "#code", unless = "#result == null")
|
||||
public MailTemplateDO getMailTemplateByCodeFromCache(String code) {
|
||||
return mailTemplateMapper.selectByCode(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MailTemplateDO> getMailTemplatePage(MailTemplatePageReqVO pageReqVO) {
|
||||
return mailTemplateMapper.selectPage(pageReqVO);
|
||||
|
@ -140,11 +121,6 @@ public class MailTemplateServiceImpl implements MailTemplateService {
|
|||
@Override
|
||||
public List<MailTemplateDO> getMailTemplateList() {return mailTemplateMapper.selectList();}
|
||||
|
||||
@Override
|
||||
public MailTemplateDO getMailTemplateByCodeFromCache(String code) {
|
||||
return mailTemplateCache.get(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatMailTemplateContent(String content, Map<String, Object> params) {
|
||||
return StrUtil.format(content, params);
|
||||
|
|
|
@ -192,6 +192,9 @@ yudao:
|
|||
ignore-caches:
|
||||
- permission_menu_ids
|
||||
- oauth_client
|
||||
- notify_template
|
||||
- mail_account
|
||||
- mail_template
|
||||
sms-code: # 短信验证码相关的配置项
|
||||
expire-times: 10m
|
||||
send-frequency: 1m
|
||||
|
|
Loading…
Reference in New Issue