文章阅读量的更新(结合redis的使用)
注解的配置(切点)
import java.lang.annotation.*;
/**
* 这个注解加载啥地方啥地方就会进行扩展,这是个切点
* 加强为切面
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface QuestionView {
/**
* 描述
*/
String description() default "";
}
切面:
import com.oppo.crm.csc.extension.tally.financiala.infrastructure.utils.IpUtils;
import com.oppo.crm.csc.extension.tally.financiala.infrastructure.utils.RedisUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* 将访问该问题的 ip存入 redis 中, key为文章id,value为ip地址
*/
@Aspect
@Configuration
public class PageViewAspect {
Logger log= LoggerFactory.getLogger(IpUtils.class);
@Resource
private RedisUtils redisUtil;
/**
* 切入点
*/
@Pointcut("@annotation(com.oppo.crm.csc.extension.tally.financiala.application.common.anno.QuestionView)")
public void PageViewAspect() {
}
/**
* 切入处理
* @param joinPoint
* @return
*/
@Around("PageViewAspect()")
public Object around(ProceedingJoinPoint joinPoint) {
Object[] object = joinPoint.getArgs();
Object articleId = object[0];
log.info("articleId:{}", articleId);
Object obj = null;
try {
String ipAddr = IpUtils.getIpAddr();
log.info("ipAddr:{}", ipAddr);
String key = "articleId_" + articleId;
// 浏览量存入redis中
Long num = redisUtil.add(key,ipAddr);
if (num == 0) {
log.info("该ip:{},访问的浏览量已经新增过了", ipAddr);
}
obj = joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
return obj;
}
}
定时器:
import com.oppo.crm.csc.extension.tally.financiala.application.converter.UpdateQuestionTDConvert;
import com.oppo.crm.csc.extension.tally.financiala.application.dto.createquestion.PaginatedQueriesResponseDTO;
import com.oppo.crm.csc.extension.tally.financiala.application.dto.createquestion.SearchQuestionResultDTO;
import com.oppo.crm.csc.extension.tally.financiala.application.dto.createquestion.UpdateQuestionRequestDTO;
import com.oppo.crm.csc.extension.tally.financiala.application.dto.createquestion.UpdateQuestionResultDTO;
import com.oppo.crm.csc.extension.tally.financiala.application.service.QuestionService;
import com.oppo.crm.csc.extension.tally.financiala.infrastructure.utils.RedisUtils;
import com.oppo.crm.csc.extension.tally.financiala.presentation.vo.createquestion.responseparam.QuestionVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 定时任务,更新文章阅读量
*/
@Component
//@EnableScheduling
public class ArticleViewTask {
Logger log= LoggerFactory.getLogger(ArticleViewTask.class);
@Resource
private RedisUtils redisUtil;
@Resource
QuestionService questionService;
// 每天凌晨2点执行
// 同一个ip地址 在访问同一个问题时候,每天只算一个阅读量
@Scheduled(cron = "0 0 2 * * ? ")
@Transactional
public void createHyperLog() {
log.info("浏览量入库开始");
PaginatedQueriesResponseDTO paginatedQueriesResponseDTO = questionService.searchAllOnlyQuestion();
List<QuestionVO> questionVOList = paginatedQueriesResponseDTO.getQuestionVOList();
List<Long> list=new ArrayList<>();
for (QuestionVO questionVO : questionVOList) {
Long id = questionVO.getId();
list.add(id);
}
list.forEach(articleId ->{
// 获取每一篇文章在redis中的浏览量,存入到数据库中
String key = "articleId_"+articleId;
Long view = redisUtil.size(key);
if(view>0){
// 获取到当前问题id对应的阅读量
SearchQuestionResultDTO searchQuestionResultDTO = questionService.searchByQuestionId(articleId);
Integer views = Integer.parseInt(String.valueOf(view)) + searchQuestionResultDTO.getViewTotal();
// 设置新的阅读量
searchQuestionResultDTO.setViewTotal(views);
UpdateQuestionRequestDTO updateQuestionRequestDTO = UpdateQuestionTDConvert.INSTANCE.convert(searchQuestionResultDTO);
// 更新
UpdateQuestionResultDTO updateQuestionResultDTO = questionService.updateQuestionView(updateQuestionRequestDTO);
if (updateQuestionResultDTO.getSuccess()) {
log.info("数据库更新后的浏览量为:{}", views);
redisUtil.delete(key);
}
}
});
log.info("浏览量入库结束");
}
}