java面向切面编程---AOP之环绕通知
package com.xlkh.bigscreen.common.aspect;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xlkh.bigscreen.common.utils.RedisDeviceUtil;
import com.xlkh.bigscreen.service.bigscreen.BigscreenRedisService;
import com.xlkh.bigscreen.service.census.BigscreenCensusSqlService;
import lombok.SneakyThrows;
import net.sf.json.JSONArray;
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.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
public class MyAspect {
@Autowired
@Resource(name = "redisTemplate3")
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private RedisDeviceUtil redisDeviceUtil;
@Value("${spring.redis3.database:3}")
private int database;
String params="";
@Autowired
private BigscreenCensusSqlService bigscreenCensusSqlService;
@Autowired
private BigscreenRedisService bigscreenRedisService;
//这里是查询缓存的 所以应该放入缓存的操作
public Logger logger=LoggerFactory.getLogger(MyAspect.class);
//定义切面
@Pointcut(value = "execution(* com.xlkh.bigscreen.controller.census.BigscreenCensusCommonController.getCensusBy*(..))")
public void myPointcut(){
}
//定义环绕通知 缓存操作
@SneakyThrows
@Around("myPointcut()")
public Object cacheOperation(ProceedingJoinPoint proceedingJoinPoint){
//获取类名
String className=proceedingJoinPoint.getTarget().toString();
//获取方法名
String methodName=proceedingJoinPoint.getSignature().getName();
//获取参数
Object[] array=proceedingJoinPoint.getArgs();
ObjectMapper mapper=new ObjectMapper();
logger.info("方法执行之前--"+className+":"+methodName+"传递的参数--"+mapper.writeValueAsString(array));
String key="";
if (array.length>0){
for (int i = 0; i <array.length ; i++) {
if (null!=array[i]){
key=key.concat("_"+(String) array[i]);
}
}
}
int i = key.indexOf("_");
System.err.println("方法----"+methodName);
String redisKey="CACHE:"+key.substring(i+1,key.length());
//通过key去查询Redis的缓存
Object object = redisTemplate.opsForValue().get(redisKey);
if (null!=object){
logger.info("查询的是Redis的数据,查询的key是:"+redisKey);
JSONArray jsonArray = JSONArray.fromObject(object);
return jsonArray;
}
//Redis未查询到结果--查询相应的数据源
//环绕 控制整个目标函数去执行
List<Object> proceed = (List<Object>) proceedingJoinPoint.proceed();
if (proceed.size()==0){
redisTemplate.opsForValue().set(redisKey,"[]");
//10秒过期
redisTemplate.expire(redisKey,10, TimeUnit.SECONDS);
}else {
redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(proceed));
// //2天过期
// redisTemplate.expire(redisKey,2, TimeUnit.DAYS);
//20秒过期
redisTemplate.expire(redisKey,20, TimeUnit.SECONDS);
}
return proceed;
}
}
接口的路径

使用AOP的作用其实就是在访问方法的时候,根据类名方法名以及传入的参数组装成redis的key,然后去redis查询数据
浙公网安备 33010602011771号