首页 > 代码库 > ssm+redis整合(通过aop自定义注解方式)

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="http://www.mamicode.com/id")
    public User getUser(int id) throws BaseServiceException{
        return userMapper.getUserById(id);
    }

}

 

ssm+redis整合(通过aop自定义注解方式)