此方案借助aop自定義注解來創建redis緩存機制。
1、創建自定義注解類
package com.tp.soft.common.util; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface CacheAnnotation { String name() default ""; String value() default ""; }
2、創建aop切面類
package com.tp.soft.aop; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import com.tp.soft.common.util.CacheAnnotation; import com.tp.soft.entity.User; import com.tp.soft.redis.RedisCacheAn; @Aspect public class CacheRedisAop { @Pointcut("@annotation(com.tp.soft.common.util.CacheAnnotation)") public void pointCutMethod(){ } @Around("pointCutMethod()") public Object around(ProceedingJoinPoint pjp) throws Throwable{ //獲取緩存的唯一key格式ID String cacheKey = getCacheKey(pjp); RedisCacheAn ra = new RedisCacheAn(cacheKey); //從redis獲取緩存數據 Object obj = (Object) ra.getObject(cacheKey); //存在直接返回,不再接下去執行查詢數據庫操作 if(obj != null){ return obj; } //不存在執行數據庫操作 Object proceed = pjp.proceed(); //將查詢的對象存入redis緩存 ra.putObject(cacheKey,proceed); return proceed; } private String getCacheKey(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException { Signature signature = pjp.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method targetMethod = methodSignature.getMethod(); Class<? extends Object> cls = pjp.getTarget().getClass(); Object[] args = pjp.getArgs(); Method method = cls.getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes()); String name = method.getAnnotation(CacheAnnotation.class).name(); String value = method.getAnnotation(CacheAnnotation.class).value(); String[] split = value.split(","); for (String field : split) { name += "." + field; } String id = ""; if(args != null && args.length>0){ id = String.valueOf(args[0]); } name += "=" + id; String redisKey = method + "." + name; //查詢緩存是否存在 return redisKey; } }
切面注解@annotation 只要在方法上注解@CacheAnnotation 就進入AOP該類進行處理,所以在要進入緩存機制的業務層注入這個寫的自定義注解,具體的一些redis獲取緩存鏈接對象的類在之前的
ssm+redis整合(通過cache方式)
ssm+redis整合之redis連接池注入
都有寫到,可以參考
3、接下來就是在業務層需要緩存的方法上加入注解就可以了,其中name 和value 2個屬性主要是為了生成唯一的redis keyid
package com.tp.soft.service.sys.impl; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.tp.soft.common.exception.BaseServiceException; import com.tp.soft.common.util.CacheAnnotation; import com.tp.soft.dao.UserMapper; import com.tp.soft.entity.User; import com.tp.soft.service.sys.UserSvc; @Service("userService") public class UserSvcImpl implements UserSvc{ @Resource private UserMapper userMapper; @CacheAnnotation(name="user",value="id") public User getUser(int id) throws BaseServiceException{ return userMapper.getUserById(id); } }