AOP+Redis实现缓存

今天早上用AOP+redis实现缓存,记录一下

配置文件:spring配置文件:记得开启注解


	
	
	

	
	
	
	
        
        
        
        
	
	
	
	
	
	
	
	
	
	
	
		
	
	
	
	
		
			
			
			
			
			
		
	
	
	
	
		
		
		
	
	
	

Redis配置文件:





	 
	 
	   
	 
		
		
	 


	 
	 
	
	 
	

redis.properties配置文件:

redis.host=192.168.169.130   对应我搭建redis的虚拟机号
redis.port=6379

具体代码:

1 自定义注解

package com.jt.manage.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解
 * @author Administrator
 *
 */

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheAnno {

	String key();		//定义key值
	int index();		//定义参数位置  用户传多参时用
	Class targetClass(); //定义目标类型
	CACHE_TYPE cacheType() default CACHE_TYPE.FIND;
	
	/**
	 * 查找和更新缓存的处理方法不一样,更新逻辑为先删除再同步数据到缓存
	 * @author Administrator
	 *
	 */
	enum CACHE_TYPE{
		FIND,		//定义查找
		UPDATE		//定义更新
	}
	
}

2.编写切面:

package com.jt.manage.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.jt.common.util.ObjectMapperUtil;
import com.jt.manage.anno.CacheAnno;
import com.jt.manage.anno.CacheAnno.CACHE_TYPE;

import redis.clients.jedis.Jedis;

/**
 * 定义cache缓存的aop切面  记得开启注解标签
 * @author Administrator
 *
 */
@Component	//交给spring容器管理
@Aspect		//标识切面
public class CacheAspect {

	@Autowired
	private Jedis jedis; //注入redis
	
	//定义只拦截类型为CacheAnno类型的注解
	@Around("@annotation(cacheAnn)")
	public Object around(ProceedingJoinPoint joinPoint,CacheAnno cacheAnn) {
		return getObject(joinPoint,cacheAnn);
	}

	public Object getObject(ProceedingJoinPoint joinPoint, CacheAnno cacheAnn) {
		//获取注解中需要的四个参数
		CACHE_TYPE cacheType = cacheAnn.cacheType();
		String 	key = cacheAnn.key();
		int index = cacheAnn.index();
		Class targetClass = cacheAnn.targetClass();
		
		//根据位置获取目标方法的参数   getArgs()返回Object[]
		Long id =  (Long) joinPoint.getArgs()[index];
		
		//拼接参数 ITEM_CAT_0
		String redisKey = key + id;
		Object object = null;
		switch (cacheType) {
		case FIND:		//表示查询缓存
			object = findObject(joinPoint,redisKey,targetClass);
			break;
		case UPDATE:	//表示更新缓存
			object = updateObject(joinPoint,redisKey);
			break;
		}
		return object;
	}

	private Object findObject(ProceedingJoinPoint joinPoint, String key, Class targetClass) {
		
		//检查缓存中是否有数据
		String result = jedis.get(key);
		Object object = null;
		try {
			if(StringUtils.isEmpty(result)) {
				//表示缓存中没有数据,则查询数据库
				//执行目标方法查询数据库
				object = joinPoint.proceed();
				//将查出的数据转成json串放入缓存(调用工具类)
				String json = ObjectMapperUtil.toJSON(object);
				jedis.set(key, json);
				System.out.println("AOP查询真实数据库!!");
			}else {
				//表示缓存中有数据,查询缓存
				object = ObjectMapperUtil.toObject(result, targetClass);
				System.out.println("AOP查询缓存!!");
			}
		} catch (Throwable e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		return object;
	}

	private Object updateObject(ProceedingJoinPoint joinPoint, String redisKey) {
		//更新缓存,删除即可
		Object object = null;
		try {
			jedis.del(redisKey);
			object = joinPoint.proceed();
			System.out.println("AOP缓存删除");
		} catch (Throwable e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		return object;
	}
}

3.在目标方法上添加注解

@Override
	@CacheAnno(cacheType=CACHE_TYPE.FIND,index=0,key="ITEM_CAT_",targetClass=ArrayList.class)
	public List findItemCatList(Long parentId) {
		List treeList = new ArrayList();
		
		List itemCatList   = findItenCatByParentId(parentId);
		for (ItemCat itemCat : itemCatList ) {
			EasyUITree easyUITree = new EasyUITree();
			easyUITree.setId(itemCat.getId());
			easyUITree.setText(itemCat.getName());
			//一二级使用closed  三级使用open
	        String state = itemCat.getIsParent()?"closed":"open";
	        easyUITree.setState(state);
	        treeList .add(easyUITree);
		}
		System.out.println("我是目标方法查询数据库");
		return treeList;
	}

测试

AOP+Redis实现缓存_第1张图片

你可能感兴趣的:(ssm)