springboot自定义redis缓存机制

核心代码

启动类

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("修改数据库");
	}

}

完整项目请下载

https://download.csdn.net/download/weixin_41796956/11264308

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值