2018-09-24
9856 ワード
SpringbootでのAOP+redisパッケージキャッシュ
目次
一、目的二、配置--1、pom.xml--2、redis構成--3、応答クラス--4、AOPカットの構成三、自作キャッシュの使い方
一、目的
コントロールレイヤのメソッドにコメントを付けるとaop接面を利用してコードの拡張を行い,コードの拡張ではredisをキャッシュミドルウェアとして利用することができる.注記についてはカスタム
1、pom.xml
2、redis配置
注意:ここのテンプレートには文字とオブジェクトがあります.valueが文字の場合、文字テンプレートが推奨されます.
3、応答クラス
4、AOP切面の配置
注意:1、キャッシュされたkeyの一意性はurlで保証され、ここではGetリクエストのみが許可され、拡張したい場合は自分でコードを修正し、keyの一意性も他の方法で決定することができます.2、ここでは
三、自分で書いたキャッシュプログラムの使い方
目次
一、目的二、配置--1、pom.xml--2、redis構成--3、応答クラス--4、AOPカットの構成三、自作キャッシュの使い方
一、目的
コントロールレイヤのメソッドにコメントを付けるとaop接面を利用してコードの拡張を行い,コードの拡張ではredisをキャッシュミドルウェアとして利用することができる.注記についてはカスタム
@RedisCached
二、配置1、pom.xml
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-data-redis
2、redis配置
@Configuration
public class RedisConfig {
/**
* @Description: , redis { @link RedisTemplate}
* @Author: maozi
* @Date: 2018/6/5 11:49
* @see:
**/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(factory);
return template;
}
}
@Repository
public class RedisDao {
/**
* @Description: { @link }
* @Author: maozi
* @Date: 2018/6/5 11:52
* @see:
**/
@Autowired
private StringRedisTemplate stringTemplate;
/**
* @Description: { @link }
* @Author: maozi
* @Date: 2018/6/5 11:53
* @see:
**/
@Autowired
private RedisTemplate template;
public void setStringKey(String key, String value,int expire) {
if(stringTemplate.hasKey(key)){
stringTemplate.delete(key);
}
ValueOperations ops = stringTemplate.opsForValue();
ops.set(key,value,expire, TimeUnit.MINUTES);
}
public String getStringValue(String key) {
ValueOperations ops = this.stringTemplate.opsForValue();
return ops.get(key);
}
public Object getValue(String key) {
return template.opsForValue().get(key);
}
public void setKey(String key,Object value,long minutes){
if(template.hasKey(key)){
template.delete(key);
}
template.opsForValue().set(key,value,minutes, TimeUnit.MINUTES);
}
public boolean existByKey(String key){
return template.hasKey(key);
}
public boolean existByStringKey(String key){
return stringTemplate.hasKey(key);
}
public long getExpireTime(String key){
return template.getExpire(key);
}
public Boolean setExpireToReturnYes(String key,long timeout){
if (!template.hasKey(key)){
return false;
}
return template.expire(key,timeout,TimeUnit.MINUTES);
}
public Boolean setStringExpireToReturnYes(String key,long timeout){
if(!stringTemplate.hasKey(key)){
return false;
}
return stringTemplate.expire(key,timeout,TimeUnit.MINUTES);
}
public void cleanCacheByString(String key){
stringTemplate.delete(key);
}
public void cleanCache(String key){
template.delete(key);
}
}
注意:ここのテンプレートには文字とオブジェクトがあります.valueが文字の場合、文字テンプレートが推奨されます.
application.properties
# redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=1
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=500
spring.redis.pool.min-idle=0
spring.redis.timeout=0
3、応答クラス
@ApiModel(description = " ")
public class ResponseResult {
private String errorCode;
private String errorMsg;
private Object objectResult;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public Object getObjectResult() {
return objectResult;
}
public void setObjectResult(Object objectResult) {
this.objectResult = objectResult;
}
@Override
public String toString(){
return JSON.toJSONString(this);
}
}
4、AOP切面の配置
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RedisCached {
public int expire() default 5;// , 5
}
/**
* @Description: redis AOP
* @Author: maozi
* @Date: 2018/9/3 10:07
* @see: RedisCached
**/
@Aspect
@Component
public class RedisAspect {
private final Logger logger = LoggerFactory.getLogger(RedisAspect.class);
@Autowired
RedisDao redisDao;
@Pointcut("execution(public com.zhengjia.entity.ResponseResult com.zhengjia.web.*.*(..)) && @annotation(com.zhengjia.common.Annotation.RedisCached)")
public void redisAdvice(){}
@Around("redisAdvice()")
public Object Interceptor(ProceedingJoinPoint pjp){
Object result = null;
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
String port = String.valueOf(request.getServerPort());
String uri = request.getRequestURI();
String methodType = request.getMethod();
String queryString = request.getQueryString();
//
Method method=getMethod(pjp);
// annotation
RedisCached annotation = method.getAnnotation(RedisCached.class);
int expire = annotation.expire();
//
if(!methodType.equalsIgnoreCase("GET")){
throw new RuntimeException(" get ");
}
//key url
String keyName = "";
if(method.getAnnotation(IgnoreToken.class) == null){ // ,keyName sourceFrom
String token = request.getHeader("Authorization");
if(token.isEmpty()) throw new RuntimeException(" Authorization token ");
Map userMap = (Map)redisDao.getValue(token);
keyName = (String)userMap.get("sourceFrom") + port + uri + "?" + queryString;
}else {
keyName = port + uri + "?" + queryString;
}
ResponseResult responseResult = new ResponseResult();
try {
if (!redisDao.existByKey(keyName)){// ,
result = pjp.proceed();
responseResult = (ResponseResult)result;
if(responseResult.getObjectResult() != null){ //
redisDao.setKey(keyName,responseResult.getObjectResult(),expire);
}
}else{// ,
responseResult.setObjectResult(redisDao.getValue(keyName));
responseResult.setErrorCode(Constants.RESPONSE_CODE_SUCCESS);
responseResult.setErrorMsg(Constants.RESPONSE_MSG_OK);
result = responseResult;
logger.info("redis ,key " + keyName);
}
} catch (Throwable e) {
e.printStackTrace();
responseResult.setErrorCode(Constants.RESPONSE_CODE_ERROR);
responseResult.setErrorMsg("redisAspect !");
logger.info("redisAspect !");
}
return result;
}
/**
*
*
* MethodSignature.getMethod()
*
*
*/
public Method getMethod(ProceedingJoinPoint pjp){
//
Object [] args=pjp.getArgs();
Class [] argTypes=new Class[pjp.getArgs().length];
if(args.length == 1 && args[0] == null){
args = new Object[0];
}
for(int i=0;i 0){
method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argTypes);
}else { //
Class clazz = Class.forName(pjp.getSignature().getDeclaringTypeName());
Method[] i = clazz.getMethods();
for(Method data : clazz.getMethods()){
if(data.getName().equalsIgnoreCase(pjp.getSignature().getName())){
method = data;
break;
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return method;
}
}
注意:1、キャッシュされたkeyの一意性はurlで保証され、ここではGetリクエストのみが許可され、拡張したい場合は自分でコードを修正し、keyの一意性も他の方法で決定することができます.2、ここでは
ResponseResult
のobjectResultの値をキャッシュするので、ResponseResultで戻ります.また、戻り値が切面で制限されているためです.つまり、ResponseResultで戻り値を返さなくても、このキャッシュは機能しません.3、expireは提供され、動的にキャッシュの期限切れの時間を設定する三、自分で書いたキャッシュプログラムの使い方
/**
* -
*/
@GetMapping(value = "/correlation-degree/{name}")
@RedisCached(expire = 6)
public ResponseResult shopMallCorrelationDegree(@PathVariable String name) {
ResponseResult responseResult = new ResponseResult();
List