应用场景:页面加载完成后异步ajax请求后台获取下拉框、列表数据等。后台controller层调用其他服务提供的接口实现数据查询。为了防止频繁的调用其他服务的接口,减少对其他服务的请求压力。在获取了数据以后把数据缓存到redis中,下次相同请求判断距离上次请求是否在有效期内,如果是,就直接从redis取数据返回。
难点:如何在最少更改现有系统的基础上实现此功能,用面向切面编程aop的思想切入controller方法,用注解的方式是比较理想的。把数据序列化和反序列化后实现数据在redis缓存中存取。
1. 定义一个注解
此注解作用在controller方法,指定方法是否使用缓存。由于是根据项目业务要求,此注解使用的http请求是get的方式,而且使用了@ResponseBody注解。
package com.lancy.common.util.annotation.DataCacheable;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 由于spring缓存注解不具备在方法上自定义缓存时间,而且如果在controller上异步请求的方法( @ResponseBody)上进行一些个性化的改造不好改,可以使用此注解
*
* @version V1.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataCacheable {
// 缓存的key,默认是方法签名和方法 参数做key
String value() default "";
// 缓存的时间,默认30分钟 (秒为单位)
int exp() default 1800;
}
2. aop实现
package com.lancy.web.interceptor;
import java.io.UnsupportedEncodingException;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation