ssm+redis整合(通过aop自定义注解方式)
此方案借助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); } }