核心代码
启动类
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@SpringBootApplication
@EnableAspectJAutoProxy
@MapperScan(basePackages = "com.sykj.mapper")
public class SpringbootStartApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootStartApplication.class, args);
}
}
自定义缓存注解
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomCache {
String key();
String pre();//前缀
boolean refresh()default false;//是否清除缓存
}
注解配置类
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import com.sykj.util.RedisUtil;
/**
* 首先要在spring启动类开启切面编程
* @author Administrator
*
*/
@Component
@Aspect
public class CustomCacheConfiguration {
@Autowired
private RedisUtil redisUtil;
//定义一个方法 使用注解触发这个缓存方法
//@annotation()这是一个语法,当出现这个注解的时候触发该方法
@Around("@annotation(com.sykj.cache.CustomCache)")
public Object queryCache(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("方法执行之前-----增强");
//获取查询的key 连接点是在方法上的,所以可以强转成方法的签名信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取被注解注释的方法
Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getMethod().getParameterTypes());
CustomCache customCache = method.getAnnotation(CustomCache.class);
//获取注解中的key
String ELkey=customCache.key();
String pre=customCache.pre();
boolean refresh = customCache.refresh();
//通过注解中的el表达式获取参数中的值
//1.创建表达式
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(ELkey);
//2.设置解析上下文(有哪些占位符以及占位符的值)
EvaluationContext context = new StandardEvaluationContext();
Object[] args = joinPoint.getArgs();//获取方法里的参数值
//获取方法真实参数名
ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
//将方法的参数名和参数值设置在解析器里
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
//获取将占位符替换成真实参数后的key
String key = expression.getValue(context).toString();
//判断是否需要清除缓存
if(!refresh){
//查询redis中是否存在
Object obj = redisUtil.getObject(pre+key);
if(obj!=null){
System.out.println("查询到缓存,直接从缓存中获取");
return obj;
}else{
//代表执行带注解的方法,不执行这一行代表不执行被CustomCache注解的方法
Object proceed = joinPoint.proceed();
System.out.println("方法执行之后-----增强");
//不存在则将数据添加到redis中
redisUtil.set(pre+key,proceed);
return proceed;
}
}else{
redisUtil.delete(pre+key);
//代表执行带注解的方法,不执行这一行代表不执行被CustomCache注解的方法
Object proceed = joinPoint.proceed();
System.out.println("方法执行之后-----增强");
return proceed;
}
}
}
调用的地方需要在方法体上加注解
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sykj.bean.Job;
import com.sykj.cache.CustomCache;
import com.sykj.mapper.JobMapper;
import com.sykj.servce.IJobService;
@Service
public class JobServiceImpl implements IJobService {
@Autowired
private JobMapper jobMapper;
@Override
@CustomCache(key="#jobId",pre="job_")
public Job selectByPrimaryKey(Integer jobId) {
System.out.println("查询数据库");
return jobMapper.selectByPrimaryKey(jobId);
}
@Override
@CustomCache(key="#jobId",pre="job_",refresh=true)
public void updateByPrimaryKey(Integer jobId) {
System.out.println("修改数据库");
}
}